Add files via upload
This commit is contained in:
409
Beal.ipynb
409
Beal.ipynb
@@ -5,16 +5,15 @@
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": true,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"<div style=\"text-align:right\">**Peter Norvig** 22 October 2015, revised 28 October 2015</div>\n",
|
||||
"<div style=\"text-align:right\"><b>Peter Norvig</b> 22 October 2015, revised 28 October 2015, 4 July 2017</div>\n",
|
||||
"\n",
|
||||
"# Beal's Conjecture Revisited<sup>2</sup>\n",
|
||||
"# Beal's Conjecture Revisited\n",
|
||||
"\n",
|
||||
"In 1637, Pierre de Fermat wrote in the margin of a book that he had a proof of his famous \"[Last Theorem](https://en.wikipedia.org/wiki/Fermat%27s_Last_Theorem)\":\n",
|
||||
"\n",
|
||||
@@ -29,15 +28,13 @@
|
||||
"> <br>where $A, B, C, x, y, z$ are positive integers and $x, y, z$ are all greater than $2$, \n",
|
||||
"> <br>then $A, B$ and $C$ must have a common prime factor.\n",
|
||||
"\n",
|
||||
"[Andrew Wiles](https://en.wikipedia.org/wiki/Andrew_Wiles) proved Fermat's theorem in 1995, but Beal's offer of [\\$1,000,000](http://abcnews.go.com/blogs/headlines/2013/06/billionaire-offers-1-million-to-solve-math-problem/) for a proof or disproof of *his* conjecture remains unclaimed. I don't have the mathematical skills of Wiles, so all I can do is write a program to search for counterexamples. I first wrote [that program in 2000](http://norvig.com/beal2000.html), and [my name got associated](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=beal%20conjecture) with Beal's Conjecture, which means I get a lot of emails with purported proofs or counterexamples (many asking how they can collect their prize money). So far, all the emails have been wrong. This page catalogs some of the more common errors—including two mistakes of my own—and shows an updated program."
|
||||
"[Andrew Wiles](https://en.wikipedia.org/wiki/Andrew_Wiles) proved Fermat's theorem in 1995, but Beal's conjecture remains unproved, and Beal has offered [\\$1,000,000](http://abcnews.go.com/blogs/headlines/2013/06/billionaire-offers-1-million-to-solve-math-problem/) for a proof or disproof. I don't have the mathematical skills of Wiles, so I could never find a proof, but I can write a program to search for counterexamples. I first wrote [that program in 2000](http://norvig.com/beal2000.html), and [my name got associated](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=beal%20conjecture) with Beal's Conjecture, which means I get a lot of emails with purported proofs or counterexamples (many asking how they can collect their prize money). So far, all the emails have been wrong. This page catalogs some of the more common errors and updates my 2000 program."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -47,7 +44,7 @@
|
||||
"# How to Not Win A Million Dollars\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"* A proof must show that there are no examples that satisfy the conditions. A common error is to show how a certain technique generates an infinite collection of numbers that satisfy $A^x + B^y = C^z$ and then show that in all of these, $A, B, C$ have a common factor. But that's not good enough, unless you can also prove that no other technique can satisfy the equation.\n",
|
||||
"* A proof must show that there are no examples that satisfy the conditions. A common error is to show how a certain pattern generates an infinite collection of numbers that satisfy $A^x + B^y = C^z$ and then show that in all of these, $A, B, C$ have a common factor. But that's not good enough, unless you can also prove that no other pattern exists.\n",
|
||||
"\n",
|
||||
"<p>\n",
|
||||
"\n",
|
||||
@@ -63,7 +60,7 @@
|
||||
"$A^x + B^y = C^z$ <br>\n",
|
||||
"$A, B, C$ have no common prime factor.\n",
|
||||
"\n",
|
||||
"(If you think you have a valid counterexample, before you share it with Andrew Beal, or me, or anyone else, you can check it with my [Online Beal Counterexample Checker](http://norvig.com/bealcheck.html).)\n",
|
||||
"(If you think you might have a valid counterexample, before you share it with Andrew Beal or anyone else, you can check it with my [Online Beal Counterexample Checker](http://norvig.com/bealcheck.html).)\n",
|
||||
"\n",
|
||||
"<p>\n",
|
||||
"\n",
|
||||
@@ -92,7 +89,6 @@
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": true,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -108,8 +104,6 @@
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -139,14 +133,13 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"**WOW!** The result is `True`! Is this a real counterexample to Beal? And also a disproof of Fermat?\n",
|
||||
"**WOW! The result is `True`!** Is this a real counterexample to Beal? And also a disproof of Fermat?\n",
|
||||
"\n",
|
||||
"Alas, it is not. Notice the decimal point in \"`3.`\", indicating a floating point number, with inexact, limited precision. Change the inexact \"`3.`\" to an exact \"`3`\" and the result changes to \"`False`\". Below we see that the two sides of the equation are the same for the first 18 digits, but differ starting with the 19th: "
|
||||
]
|
||||
@@ -156,8 +149,6 @@
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -185,7 +176,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -194,9 +184,11 @@
|
||||
"source": [
|
||||
"They say \"close\" only counts in horseshoes and hand grenades, and if you threw two horseshoes at a stake on the planet [Kapteyn-b](https://en.wikipedia.org/wiki/Kapteyn_b) (a possibly habitable and thus possibly horseshoe-playing exoplanet 12.8 light years from Earth) and the two paths differed in the 19th digit, the horseshoes would end up [less than an inch](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=12.8%20light%20years%20*%201e-19%20in%20inches) apart. That's really, really close, but close doesn't count in number theory.\n",
|
||||
"\n",
|
||||
"Another near-solution was proposed by Mustafa Pehlivan: $193^{33554432} + 33554432^{193} = 37249^{16777216}$. Both $193^{33554432}$ and $37249^{16777216}$ are 76,690,578-digit numbers (while $33554432^{193}$ is a puny 1,453 digits), so it is possible that the two sides are equal, and in fact they agree in all but the last 4 of the 76 million digits. There is no analogy I can make in the physical universe that is that close.\n",
|
||||
"\n",
|
||||
"# *The Simpsons* and Fermat\n",
|
||||
"\n",
|
||||
"Speaking of *close*: in two different [episodes of *The Simpsons*](http://www.npr.org/sections/krulwich/2014/05/08/310818693/did-homer-simpson-actually-solve-fermat-s-last-theorem-take-a-look), close counterexamples to Fermat's Last Theorem are shown: \n",
|
||||
"In two different [episodes of *The Simpsons*](http://www.npr.org/sections/krulwich/2014/05/08/310818693/did-homer-simpson-actually-solve-fermat-s-last-theorem-take-a-look), close counterexamples to Fermat's Last Theorem are shown: \n",
|
||||
"$1782^{12} + 1841^{12} = 1922^{12}$ and $3987^{12} + 4365^{12} = 4472^{12}$. These were designed by *Simpsons* writer David X. Cohen to be correct up to the precision found in most handheld calculators. Cohen found the equations with a program that must have been something like this:"
|
||||
]
|
||||
},
|
||||
@@ -205,8 +197,6 @@
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -242,8 +232,6 @@
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -251,44 +239,32 @@
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(1782, 1841, 1922, 12)"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"ename": "NameError",
|
||||
"evalue": "name 'esimpsons' is not defined",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[0;32m<ipython-input-5-c5d9ee9dd94c>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mesimpsons\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1000\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m11\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m12\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m13\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||
"\u001b[0;31mNameError\u001b[0m: name 'esimpsons' is not defined"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"simpsons(range(1000, 2000), [11, 12, 13])"
|
||||
"esimpsons(range(1000, 2000), [11, 12, 13])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(3987, 4365, 4472, 12)"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"simpsons(range(3000, 5000), [12])"
|
||||
]
|
||||
@@ -297,32 +273,29 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# Back to Beal: `beal` 2.0 and 2.1\n",
|
||||
"# Back to Beal\n",
|
||||
"\n",
|
||||
"In October 2015 I looked back at my original [program from 2000](http://norvig.com/beal2000.html).\n",
|
||||
"I ported it from Python 1.5 to 3.5 (by putting parens around the argument to `print` and adding `long = int`). It runs 250 times faster today, a tribute to both computer hardware engineers and the developers of the Python interpreter.\n",
|
||||
"I ported it from Python 1.5 to 3.5 (by putting parens around the argument to `print` and adding `long = int`). The program runs 250 times faster today than it did in 2000, a tribute to both computer hardware engineers and the developers of the Python interpreter.\n",
|
||||
"\n",
|
||||
"I found that I had misunderstood [the problem in 2000](https://web.archive.org/web/19991127081319/http://bealconjecture.com/). I thought that, *by definition*, $A$ and $B$ could not have a common factor, but actually, the definition of the conjecture only rules out examples where all three of $A, B, C$ share a common factor. I rewrote the program to reflect that, but then [Mark Tiefenbruck ](mailto:mark @tiefenbruck.org) (and later Edward P. Berlin and Shen Lixing) wrote to point out that my original program was actually correct, not by definition, but by derivation: if $A$ and $B$ have a commmon prime factor $p$, then the sum of $A^x + B^y$ must also have that factor $p$, and since $A^x + B^y = C^z$, then $C^z$ and hence $C$ must have the factor $p$. So I was wrong twice—I originally failed to understand the problem completely, and then I failed to recognize the optimization—and that means the original program was correct.\n",
|
||||
"I found that I was a bit confused about the definition of [the problem in 2000](https://web.archive.org/web/19991127081319/http://bealconjecture.com/). I thought then that, *by definition*, $A$ and $B$ could not have a common factor, but actually, the definition of the conjecture only rules out examples where all three of $A, B, C$ share a common factor. Mark Tiefenbruck (and later Edward P. Berlin and Shen Lixing) wrote to point out that my thought was actually correct, not by definition, but by derivation: if $A$ and $B$ have a commmon prime factor $p$, then the sum of $A^x + B^y$ must also have that factor $p$, and since $A^x + B^y = C^z$, then $C^z$ and hence $C$ must have the factor $p$. So I was wrong twice, and in this case two wrongs made a right.\n",
|
||||
"\n",
|
||||
"Mark Tiefenbruck also suggested another optimization: only consider exponents that are odd primes, or 4. The idea is that a number like 512 can be expressed as either $2^9$ or $8^3$, and my program doesn't need to consider both. In general, any time we have a composite exponent, such as $b^{qp}$, where $p$ is prime, we should ignore $A=b, x=qp$, and instead consider only $A=b^q, x=p$. There's one complication to this scheme: 2 is a prime, but 2 is not a valid exponent for a Beal counterexample. So we will allow 4 as an exponent, as well as all odd primes up to `max_x`.\n",
|
||||
"Mark Tiefenbruck also suggested an optimization: only consider exponents that are odd primes, or 4. The idea is that a number like 512 can be expressed as either $2^9$ or $8^3$, and my program doesn't need to consider both. In general, any time we have a composite exponent, such as $b^{qp}$, where $p$ is prime, we should ignore $b^{(qp)}$, and instead consider only $(b^q)^p$. There's one complication to this scheme: 2 is a prime, but 2 is not a valid exponent for a Beal counterexample. So we will allow 4 as an exponent, as well as all odd primes up to `max_x`.\n",
|
||||
"\n",
|
||||
"Here is the complete, updated program:"
|
||||
"Here is the complete, updated, refactored, optimized program:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -374,7 +347,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -386,26 +358,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CPU times: user 352 ms, sys: 2.2 ms, total: 354 ms\n",
|
||||
"Wall time: 354 ms\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%time beal(100, 100)"
|
||||
]
|
||||
@@ -414,7 +375,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -426,26 +386,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CPU times: user 10.8 s, sys: 143 ms, total: 11 s\n",
|
||||
"Wall time: 11.1 s\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%time beal(500, 100)"
|
||||
]
|
||||
@@ -454,7 +403,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -465,42 +413,23 @@
|
||||
"\n",
|
||||
"The function `beal` first does some precomputation, creating two data structures:\n",
|
||||
"* `Apowers`: a dict of the form `{A: [A**3, A**4, ...]}` giving the\n",
|
||||
"nonredundant powers (prime and 4th powers) of each base, `A`, from 1 to `max_x`.\n",
|
||||
"nonredundant powers (prime and 4th powers) of each base, `A`, from 3 to `max_x`.\n",
|
||||
"* `Czroots`: a dict of `{C**z : C}` pairs, giving the zth root of each power in `Apowers`.\n",
|
||||
"\n",
|
||||
"Then we consider all combinations of two bases, `A` and `B`, from `Apowers`.\n",
|
||||
"Here is a very small example Apowers table:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{1: [1],\n",
|
||||
" 2: [8, 16, 32, 128],\n",
|
||||
" 3: [27, 81, 243, 2187],\n",
|
||||
" 4: [64, 256, 1024, 16384],\n",
|
||||
" 5: [125, 625, 3125, 78125],\n",
|
||||
" 6: [216, 1296, 7776, 279936]}"
|
||||
]
|
||||
},
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Apowers = make_Apowers(6, 10)\n",
|
||||
"Apowers"
|
||||
@@ -510,50 +439,37 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"Consider the combination where `A` is `3` and `B` is `6`. Of course `gcd(3, 6) == 3`, so the program would not consider them further, but imagine if they did not share a common factor. Then we would look at all possible `Ax + By` sums, for `Ax` in `[27, 81, 243, 2187]` and `By` in `[216, 1296, 7776, 279936].` One of these would be `27 + 216`, which sums to `243`. We look up `243` in `Czroots`:"
|
||||
"Then we enumerate all combinations of two bases, `A` and `B`, from `Apowers`. Consider the combination where `A` is `3` and `B` is `6`. Of course `gcd(3, 6) == 3`, so the program would not consider them further, but imagine if they did not share a common factor. Then we would look at all possible `Ax + By` sums, for `Ax` in `[27, 81, 243, 2187]` and `By` in `[216, 1296, 7776, 279936].` One of these would be `27 + 216`, which sums to `243`. We look up `243` in `Czroots`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{128: 2, 1: 1, 1296: 6, 1024: 4, 32: 2, 8: 2, 64: 4, 2187: 3, 78125: 5, 256: 4, 16384: 4, 16: 2, 81: 3, 279936: 6, 243: 3, 3125: 5, 625: 5, 216: 6, 7776: 6, 27: 3, 125: 5}\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Czroots = make_Czroots(Apowers)\n",
|
||||
"print(Czroots)\n",
|
||||
"Czroots"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Czroots[243]"
|
||||
]
|
||||
},
|
||||
@@ -561,7 +477,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -578,35 +493,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"3 ** 3 + 6 ** 3 == 3 ** 5 == 243\n",
|
||||
"7 ** 7 + 49 ** 3 == 98 ** 3 == 941192\n",
|
||||
"8 ** 4 + 16 ** 3 == 2 ** 13 == 8192\n",
|
||||
"8 ** 5 + 32 ** 3 == 16 ** 4 == 65536\n",
|
||||
"9 ** 3 + 18 ** 3 == 9 ** 4 == 6561\n",
|
||||
"16 ** 5 + 32 ** 4 == 8 ** 7 == 2097152\n",
|
||||
"17 ** 4 + 34 ** 4 == 17 ** 5 == 1419857\n",
|
||||
"19 ** 4 + 38 ** 3 == 57 ** 3 == 185193\n",
|
||||
"27 ** 3 + 54 ** 3 == 3 ** 11 == 177147\n",
|
||||
"28 ** 3 + 84 ** 3 == 28 ** 4 == 614656\n",
|
||||
"34 ** 5 + 51 ** 4 == 85 ** 4 == 52200625\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def gcd(a, b): return 1\n",
|
||||
"\n",
|
||||
@@ -617,7 +512,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -629,28 +523,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{True}"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"{3 ** 3 + 6 ** 3 == 3 ** 5 == 243,\n",
|
||||
" 7 ** 7 + 49 ** 3 == 98 ** 3 == 941192,\n",
|
||||
@@ -669,7 +550,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -681,11 +561,9 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -702,7 +580,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -714,28 +591,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'tests pass'"
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def tests():\n",
|
||||
" assert make_Apowers(6, 10) == {\n",
|
||||
@@ -785,7 +649,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -794,7 +657,7 @@
|
||||
"source": [
|
||||
"The program is mostly straightforward, but relies on the correctness of these arguments: \n",
|
||||
"\n",
|
||||
"* Are we justified in taking `combinations` without replacements from the table? In other words, are we sure there are no solutions of the form $A^x + A^x = C^z$? Yes, we can be sure, because then $2\\;A^x = C^z$, and all the factors of $A$ would also be factors of $C$.\n",
|
||||
"* Are we justified in taking `combinations` without replacements from the `Apowers` table? In other words, are we sure there are no solutions of the form $A^x + A^x = C^z$? Yes, we can be sure, because then $2\\;A^x = C^z$, and all the factors of $A$ would also be factors of $C$.\n",
|
||||
"\n",
|
||||
"<p>\n",
|
||||
"* Are we justified in having a single value for each key in the `Czroots` table? Consider that $81 = 3^4 = 9^2$. We put `{81: 3}` in the table and discard `{81: 9}`, because any number that has 9 as a factor will always have 3 as a factor as well, so 3 is all we need to know. But what if a number could be formed with two bases where neither was a multiple of the other? For example, what if $2^7 = 5^3 = s$; then wouldn't we have to have both 2 and 5 as values for $s$ in the table? Fortunately, that can never happen, because of the [fundamental theorem of arithmetic](https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic).\n",
|
||||
@@ -803,7 +666,7 @@
|
||||
"* Could there be a rounding error involving the `exponent` function that was not caught by the tests? Possibly; but `exponent` is not used to find counterexamples, only to print them, so any such error wouldn't cause us to miss a counterexample.\n",
|
||||
"\n",
|
||||
"<p>\n",
|
||||
"* Are we justified in only considering exponents that are odd primes, or the number 4? In one sense, yes, because when we consider the two terms $A^{qp}$ and $(A^q)^p$, we find they are always equal, and always have the same prime factors (the factors of $A$), so for the purposes of the Beal problem, they are equivalent, and we only need consider one of them. In another sense, there is a difference. With this optimization, when we run `beal(6, 10)`, we are no longer testing $512$ as a value of $A$ or $B$, even though $512 = 2^9$ and both $2$ and $9$ are within range, because the program chooses to express $512$ as $8^3$, and $8$ is not in the specified range. So the program is still correctly searching for counterexamples, but the space that it searches for given `max_A` and `max_x` is different with this optimization.\n",
|
||||
"* Are we justified in only considering exponents that are odd primes, or the number 4? In one sense, yes, because when we consider the two terms $A^{(qp)}$ and $(A^q)^p$, we find they are always equal, and always have the same prime factors (the factors of $A$), so for the purposes of the Beal problem, they are equivalent, and we only need consider one of them. In another sense, there is a difference. With this optimization, when we run `beal(6, 10)`, we are no longer testing $512$ as a value of $A$ or $B$, even though $512 = 2^9$ and both $2$ and $9$ are within range, because the program chooses to express $512$ as $8^3$, and $8$ is not in the specified range. So the program is still correctly searching for counterexamples, but the space that it searches for given `max_A` and `max_x` is different with this optimization.\n",
|
||||
"\n",
|
||||
"<p>\n",
|
||||
"* Are we really sure that when $A$ and $B$ have a common factor greater than 1, then\n",
|
||||
@@ -815,7 +678,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -825,24 +687,23 @@
|
||||
"\n",
|
||||
"# Faster Arithmetic (mod *p*)\n",
|
||||
"\n",
|
||||
"Arithmetic is slow with integers that have thousands of digits. If we want to explore much further, we'll have to make the program more efficient. An obvious improvement would be to do all the arithmetic module some prime number $p$ that fits in one word. Then we know:\n",
|
||||
"Arithmetic is slow with integers that have thousands of digits. If we want to explore much further, we'll have to make the program more efficient. An obvious improvement would be to do all the arithmetic module some number $m$. Then we know:\n",
|
||||
"\n",
|
||||
"$$\\mbox{if} ~~ \n",
|
||||
"A^x + B^y = C^z\n",
|
||||
"~~ \\mbox{then} ~~\n",
|
||||
"A^x (\\mbox{mod} ~ p) + B^y (\\mbox{mod} ~ p) = C^z \\;(\\mbox{mod} ~ p)$$\n",
|
||||
"(A^x (\\mbox{mod} ~ m) + B^y (\\mbox{mod} ~ m)) (\\mbox{mod} ~ m) = C^z \\;(\\mbox{mod} ~ m)$$\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"So we can do efficient tests modulo $p$, and then do the full arithmetic only for combinations that work modulo $p$. Unfortunately there will be collisions (two numbers that are distinct, but are equal mod $p$), so the tables will have to have lists of values. Here is a simple, unoptimized implementation:"
|
||||
"So we can do efficient tests modulo $m$, and then do the full arithmetic only for combinations that work modulo $m$. Unfortunately there will be collisions (two numbers that are distinct, but are equal mod $m$), so the tables will have to have lists of values. Here is a simple, unoptimized implementation:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": true,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -854,37 +715,37 @@
|
||||
"from itertools import combinations, product\n",
|
||||
"from collections import defaultdict\n",
|
||||
" \n",
|
||||
"def beal_modp(max_A, max_x, p=2**31-1):\n",
|
||||
"def beal_modp(max_A, max_x, m=2**31-1):\n",
|
||||
" \"\"\"See if any A ** x + B ** y equals some C ** z (mod p), with gcd(A, B) == 1.\n",
|
||||
" If so, verify that the equation works without the (mod p).\n",
|
||||
" If so, verify that the equation works without the (mod m).\n",
|
||||
" Consider any 1 <= A,B <= max_A and x,y <= max_x, with x,y prime or 4.\"\"\"\n",
|
||||
" assert p >= max_A\n",
|
||||
" Apowers = make_Apowers_modp(max_A, max_x, p)\n",
|
||||
" Czroots = make_Czroots_modp(Apowers)\n",
|
||||
" assert m >= max_A\n",
|
||||
" Apowers = make_Apowers_modm(max_A, max_x, m)\n",
|
||||
" Czroots = make_Czroots_modm(Apowers)\n",
|
||||
" for (A, B) in combinations(Apowers, 2):\n",
|
||||
" if gcd(A, B) == 1:\n",
|
||||
" for (Axp, x), (Byp, y) in product(Apowers[A], Apowers[B]): \n",
|
||||
" Czp = Axp + Byp\n",
|
||||
" if Czp in Czroots:\n",
|
||||
" for (Axm, x), (Bym, y) in product(Apowers[A], Apowers[B]): \n",
|
||||
" Czm = (Axm + Bym) % m\n",
|
||||
" if Czm in Czroots:\n",
|
||||
" lhs = A ** x + B ** y\n",
|
||||
" for (C, z) in Czroots[Czp]:\n",
|
||||
" for (C, z) in Czroots[Czm]:\n",
|
||||
" if lhs == C ** z:\n",
|
||||
" print('{} ** {} + {} ** {} == {} ** {} == {}'\n",
|
||||
" .format(A, x, B, y, C, z, C ** z)) \n",
|
||||
" \n",
|
||||
"\n",
|
||||
"def make_Apowers_modp(max_A, max_x, p): \n",
|
||||
" \"A dict of {A: [(A**3 (mod p), 3), (A**4 (mod p), 4), ...]}.\"\n",
|
||||
"def make_Apowers_modm(max_A, max_x, m): \n",
|
||||
" \"A dict of {A: [(A**3 (mod m), 3), (A**4 (mod m), 4), ...]}.\"\n",
|
||||
" exponents = exponents_upto(max_x)\n",
|
||||
" return {A: [(pow(A, x, p), x) for x in (exponents if (A != 1) else [3])]\n",
|
||||
" return {A: [(pow(A, x, m), x) for x in (exponents if (A != 1) else [3])]\n",
|
||||
" for A in range(1, max_A+1)}\n",
|
||||
"\n",
|
||||
"def make_Czroots_modp(Apowers): \n",
|
||||
" \"A dict of {C**z (mod p): [(C, z),...]}\"\n",
|
||||
"def make_Czroots_modm(Apowers): \n",
|
||||
" \"A dict of {C**z (mod m): [(C, z),...]}\"\n",
|
||||
" Czroots = defaultdict(list)\n",
|
||||
" for A in Apowers:\n",
|
||||
" for (Axp, x) in Apowers[A]:\n",
|
||||
" Czroots[Axp].append((A, x))\n",
|
||||
" for (Axm, x) in Apowers[A]:\n",
|
||||
" Czroots[Axm].append((A, x))\n",
|
||||
" return Czroots "
|
||||
]
|
||||
},
|
||||
@@ -892,7 +753,6 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -905,35 +765,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{1: [(1, 3)],\n",
|
||||
" 2: [(8, 3), (16, 4), (32, 5), (128, 7)],\n",
|
||||
" 3: [(27, 3), (81, 4), (243, 5), (187, 7)],\n",
|
||||
" 4: [(64, 3), (256, 4), (24, 5), (384, 7)],\n",
|
||||
" 5: [(125, 3), (625, 4), (125, 5), (125, 7)],\n",
|
||||
" 6: [(216, 3), (296, 4), (776, 5), (936, 7)]}"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"Apowers = make_Apowers_modp(6, 10, 1000)\n",
|
||||
"Apowers = make_Apowers_modm(6, 10, 1000)\n",
|
||||
"Apowers"
|
||||
]
|
||||
},
|
||||
@@ -941,69 +777,35 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"And each item in the `Czroots` table is of the form `{C**z (mod p): [(C, z), ...]}`.\n",
|
||||
"And each item in the `Czroots` table is of the form `{C**z (mod m): [(C, z), ...]}`.\n",
|
||||
"For example, `936: [(6, 7)]`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"defaultdict(list,\n",
|
||||
" {1: [(1, 3)],\n",
|
||||
" 8: [(2, 3)],\n",
|
||||
" 16: [(2, 4)],\n",
|
||||
" 24: [(4, 5)],\n",
|
||||
" 27: [(3, 3)],\n",
|
||||
" 32: [(2, 5)],\n",
|
||||
" 64: [(4, 3)],\n",
|
||||
" 81: [(3, 4)],\n",
|
||||
" 125: [(5, 3), (5, 5), (5, 7)],\n",
|
||||
" 128: [(2, 7)],\n",
|
||||
" 187: [(3, 7)],\n",
|
||||
" 216: [(6, 3)],\n",
|
||||
" 243: [(3, 5)],\n",
|
||||
" 256: [(4, 4)],\n",
|
||||
" 296: [(6, 4)],\n",
|
||||
" 384: [(4, 7)],\n",
|
||||
" 625: [(5, 4)],\n",
|
||||
" 776: [(6, 5)],\n",
|
||||
" 936: [(6, 7)]})"
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"make_Czroots_modp(Apowers)"
|
||||
"make_Czroots_modm(Apowers)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
@@ -1015,26 +817,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"collapsed": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"CPU times: user 9 s, sys: 145 ms, total: 9.14 s\n",
|
||||
"Wall time: 9.27 s\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%time beal_modp(500, 100)"
|
||||
]
|
||||
@@ -1043,33 +834,29 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"This is a bit faster than the previous version, and the idea is that as we start dealing with much larger integers, this version will be even faster, relatively. I could improve this version by caching certain computations, managing the memory layout better, moving some computations out of loops, considering using multiple primes (as in a Bloom filter), finding a way to parallelize the program, and re-coding in a faster compiled language (such as C++ or Go or Julia). Then I could invest thousands (or millions) of CPU hours searching for counterexamples. \n",
|
||||
"We don't see a big speedup here, but the idea is that as we start dealing with much larger integers, this version will be faster. I could improve this version by caching certain computations, managing the memory layout better, moving some computations out of loops, considering using multiple different numbers as the modulus (as in a Bloom filter), finding a way to parallelize the program, and re-coding in a faster compiled language (such as C++ or Go or Julia). Then I could invest thousands (or millions) of CPU hours searching for counterexamples. \n",
|
||||
"\n",
|
||||
"But [Witold Jarnicki](https://plus.sandbox.google.com/+WitoldJarnicki/posts) and [David Konerding](http://www.konerding.com/~dek/) already did that: they wrote a C++ program that built a table of $C^z \\;(\\mbox{mod} \\; p)$ up to $5000^{5000}$, and, in parallel across thousands of machines, searched for $A, B$ up to 200,000 and $x, y$ up to 5,000, but found no counterexamples. On a smaller scale, Edwin P. Berlin searched all $C^z$ up to $10^{17}$ and also found nothing. So I don't think it is worthwhile to continue on that path."
|
||||
"But [Witold Jarnicki](https://plus.sandbox.google.com/+WitoldJarnicki/posts) and [David Konerding](http://www.konerding.com/~dek/) already did that: they wrote a C++ program that, in parallel across thousands of machines, searched for $A, B$ up to 200,000 and $x, y$ up to 5,000, but found no counterexamples. So I don't think it is worthwhile to continue on that path.\n",
|
||||
"\n",
|
||||
"# Conclusion\n",
|
||||
"\n",
|
||||
"This was fun, but I can't recommend anyone spend a serious amount of computer time looking for counterexamples to the Beal Conjecture—the money you would have to spend in computer time would be more than the expected value of your prize winnings. I suggest you work on a proof rather than a counterexample, or work on some other interesting problem instead!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"button": false,
|
||||
"deletable": true,
|
||||
"new_sheet": false,
|
||||
"run_control": {
|
||||
"read_only": false
|
||||
}
|
||||
"collapsed": true
|
||||
},
|
||||
"source": [
|
||||
"# Conclusion\n",
|
||||
"\n",
|
||||
"This was fun, but I can't recommend anyone spend a serious amount of computer time looking for counterexamples to the Beal Conjecture—the money you invest in computer time would be more than the expected value of your prize winnings. I suggest you work on a proof rather than a counterexample, or work on some other interesting problem instead!"
|
||||
]
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
@@ -1088,9 +875,9 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.1"
|
||||
"version": "3.5.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user