A previously unnoticed property of prime numbers
quantamagazine.org
quantamagazine.org
But a little further down, the article discusses how this was discovered originally in base 3, and I think it's much simpler to understand in that context, since all primes except 3 (aka 10 base 3) end in just either 1 or 2:
"Looking at prime numbers written in base 3 — in which roughly half the primes end in 1 and half end in 2 — he found that among primes smaller than 1,000, a prime ending in 1 is more than twice as likely to be followed by a prime ending in 2 than by another prime ending in 1."
Looking at prime numbers written in base 3 — in which roughly half the primes end in 1 and half end in 2 — he found that among primes smaller than 1,000, a prime ending in 1 is more than twice as likely to be followed by a prime ending in 2 than by another prime ending in 1
is not interesting (as it seems to be just numerology), UNLESS the authors' conjecture is also true (that the statement also holds for bases > 2).they made an observation and a conjecture. If the conjecture is proven false, it's obvious uninteresting. If the conjecture isn't proven either way, it could be argued that it's just apophenia. I'm not sure I agree, but it's not an unreasonable stance.
[1]: https://www.maa.org/sites/default/files/pdf/upload_library/2...
To me, this makes for a very boring notion of "interesting."
I think most mathematicians would say that the "interestingness" of a conjecture comes from it (1) describing a phenomenon which seems "intuitively true, or very likely true" (e.g. "x^n+y^n=z^n has no solutions for n>2") combined with (2) the initial difficulty of deciding its truth/falsity using tools available at the time of its statement; along with, finally: (3) the novel techniques (sometime first arising in our brains decades or generations later!) required to ultimately determine said truth/falsity (and the degree to which these techniques touch on and illuminate other areas of mathematics).
For example, I think you'd find near-universal agreement among mathematicians that not only would the resolution of FLT (as a conjecture stated my Fermat) would have been equally "interesting" if it had been proven false -- it may have even been more surprising if a counter-example had been found (or its existence proven), provided the tools / lessons were as interesting as those in the Taylor-Wiles result we know today.
Meanwhile, some the most interesting conjectures are perhaps those that can't be decided, one way or another.
EDIT: If you don't like the idea of discussion the "what-ifs" of a conjecture that's already been decided (like FLT), just plug in any of the usual suspects, e.g. RH or GRH into what I'm saying above. Clearly, a "false" determination on any of these of these major targets -- or even a serious hint at it -- would be career-making achievement for an aspiring mathematician.
What if a counterexample with very large (x,y,z,n) had been found somewhere in the late 1980s because enough megaflops to find it was finally allocated the problem? Would that necessarily have been an interesting result?
But it's kind of a bad line of speculation (and so FLT probably wasn't the best illustrative example to bring up in my original post); again, for a real-life instance of a counter-example being found to a conjecture that had a lot of numerical evidence suggestion there wouldn't be one, have a look a the history of the Mertens Conjecture, and others of its ilk.
Basic point being that yes, counter-examples to interesting conjectures are always interesting results (and by themselves don't make the original conjecture any less interesting).
I'm curious why floating point operations would be the appropriate tool for finding solutions to a Diophantine equation. Did you have something in mind when writing this? Where can I learn more about it?
Odds are good that everyone knows the proof that all integers are "interesting". If not, the first non-interesting number would be interesting for being the first. (grin)
https://terrytao.wordpress.com/2016/03/14/biases-between-con...
It's too bad; I think it wouldn't have detracted from the article to put some more math in. It's not on the face of it at all surprising that sequential primes are more likely to be close to each other modulus any number (3, or 10, or what have you), than they are to be far apart.
By way of analogy, a train comes at 1:09pm. Trains come about every 5 minutes between 1 and 2 pm, and only on odd numbers. If you simulate a bunch of random 'next trains', 1 is much more likely than 9 because P(9) approx = !P(1,3,5,7). This is true for all bases.
I think what you'd need to be able to say to say something interesting is 1) calculate odds of finding the next prime. 2) Randomly generate numbers with a similar distribution to that of prime occurrence in that range using the Prime Number Theorem at the very least (1 / log(n) probability roughly). 3) check final digits and compare to actual distribution of final digits.
If those numbers are very different, then you have in fact found some underlying structure. But the article doesn't hit very hard on this angle, and its hard for (probably) any of us to say just thinking about it with minimal data whether or not there's structure.
> Lemke Oliver and Soundararajan’s first guess for why this bias occurs was a simple one: Maybe a prime ending in 3, say, is more likely to be followed by a prime ending in 7, 9 or 1 merely because it encounters numbers with those endings before it reaches another number ending in 3. For example, 43 is followed by 47, 49 and 51 before it hits 53, and one of those numbers, 47, is prime.
> But the pair of mathematicians soon realized that this potential explanation couldn’t account for the magnitude of the biases they found. Nor could it explain why, as the pair found, primes ending in 3 seem to like being followed by primes ending in 9 more than 1 or 7. To explain these and other preferences, Lemke Oliver and Soundararajan had to delve into the deepest model mathematicians have for random behavior in the primes.
As I'm writing this out, I'm a little less sure that this would matter, but I'll leave the comment out for the sake of discussion. :)
The first paragraph of the article links to the paper, so people who want more detail can get it. http://arxiv.org/pdf/1603.03720v1.pdf
For your second point, I don't think there's anything wrong with a paper announcing they found something interesting, even if they haven't completely analyzed every aspect of it. Getting the info out early lets a wider audience look at it, and opens their current research up to scrutiny.
By my reading, the article seems to state the key import of the finding quite clearly:
"This conspiracy among prime numbers seems, at first glance, to violate a longstanding assumption in number theory: that prime numbers behave much like random numbers."
However this statement:
If you simulate a bunch of random 'next trains', 1 is much more likely than 9 because P(9) approx = !P(1,3,5,7). This is true for all bases.
I'm afraid I don't follow at all. (Do you really mean we should expect that P(1|1) > P(1|9), for either random trains or for subsequent primes? Say wha?)
That said, perhaps you might want to skip straight to the arxiv article itself, or perhaps do some experiments on your own. It's definitely not hard to generate a non-"minimal" amount of data (out to the first few million primes or so) on one's laptop, these days.
This is fundamentally different from observations about, say, how 2 and 5 relate to decimal expansions.
P.S. never say "base 10", it's a tautology. Say "decimal"
so yeah, just hold up 10 fingers and don't say anything.
perhaps "base |||||*||", for short.
It's a non-problem though. I don't know about mathematicians, but when programmers say base N they mean N in decimal.
EDIT: woops, replied to the wrong post.
Peano would be proud.
No. There's all sorts of random nonsense in all base expansions of anything that we assign meaning to. Most base-related stuff is numerology.
> P.S. never say "base 10", it's a tautology. Say "decimal"
No, it's not. You need to specify your base number.
If you actually believe this, you must be endlessly confused when people say "base 8".
9*9+7 = 88
98*9+6 = 888
987*9+5 = 8888
While not exactly trivial, and there's still maths required to understand the patterns, this prime result is much deeper and more interesting. The GP almost passed over it because they though it might fall into the less interesting category.And most math trivia in base 10 does generalize. The numbers change, but the patterns remain the same. But base 10 is far more intuive for people.
https://en.wikipedia.org/wiki/Chebotarev%27s_density_theorem
(edit: rephrasing)
I recommend Dirichlet's Theorem on arithmetic progressions instead (everybody loves Euler's totient function!) :
https://en.wikipedia.org/wiki/Dirichlet's_theorem_on_arithme...
Quite interestingly, in all of the few cases where this doesn't hold, primes ending in the digit D are least-frequently succeeded by a prime ending in the digit D-2.
If a high school science insight seems to be able to "shoot down" a new scientific discovery, chances are what the discovery says has not really been understood properly.
The property they discovered is orthogonal to numeric base.
I think that's what the original commenter was getting at: it's not that the actual discovery is suspect, it's that the article presenting it was—even though the discovery itself is interesting.
The article talks about the last digit: That's also the remainder upon dividing by 10, a perfectly sensible thing to discuss. Similarly what it discusses in base 3 is the last digit, the remainder upon dividing by 3. Properties of numbers, particularly primes, modulo other numbers have been much studied by number theorists.
>This conspiracy among prime numbers seems, at first glance, to violate a longstanding assumption in number theory: that prime numbers behave much like random numbers...
I was under the impression that Ulam's Spiral was a much earlier indication (1960s) that primes weren't really as random as we thought.
That hints that it's an effect that asymtotically disappears...
How does this work?
For Bob, as soon as he sees a tail, his sequence is completely reset and he now has to get two tosses right.
I'm not sure how to calculate averages, though.
That makes sense.
https://www.reddit.com/r/math/comments/4abm4k/expected_numbe...
Actually, the details in the article say:
>even though head-tail and head-head have an equal chance of appearing after two coin tosses.
That implies that the tail is expected immediately after the head for Alice's goal.
But worded, "If you flip coins until you get a Head followed by a Tail, or flip coins until you get a Head followed by a Head, the answer reverts back to 4 and 6."
Very counterintuitive.
Are you saying that HH causes an early failure for HT , instead of a potentially longer success HHHT? If so , it is poorly worded, to be ambiguous about how to count failures. (In the 4-6 variation, there are no failures)
But, if you are focussing on a particular scenario that you will flip coins until you get to HT, the average number of flips will be 4, and if you flip coins until you get to HH, the average number of flips will be 6.
I just find that really hard to grasp intuitively.
But, I still find it strange that if you are flipping with one particular scenario in mind, HT or HH, that the average number of flips goes from 3 to 4 or 6, even if I can reason it out with a bit of thinking.
Seems like you're just taking a biased sample, which cancels out the differences. To take an extreme example, imagine one candidate is HHHHHHHHHH and the other candidate is any other sequence of ten flips. In the "try until you get either one" scenario, the average number of flips for either one will be 10. Testing them independently, the average number of flips for the second one will be slightly over 10, and for HHHHHHHHHH it'll be huge.
flip coins
if HT or HH
stop
vs flip coins
if HT
stop
flip coins
if HH
stop
two different scenariosIf Bob starts on H and gets T, he needs to continue flipping until he gets back to H.
Possible outcomes are: TTT, TTH, THT, THH, HTT, HTH, HHT, HHH
Alice successes are: HT, THT, and HHT, but Bob has less options: HH and THH. That's why he needs more tosses on average.
If Alice has failed to win on her second toss, her flip sequence was "HH", so she can win on the next toss, by flipping a T!
If Bob has failed to win on his second toss, his flip sequence was "HT", so he needs two more flips to win!
* HHH * THH * HTH * TTH * HHT * THT * HTT * TTT
Alice is looking for HT, so she will succeed in HTH, HHT, THT, HTT, that is 4 out of 8 possible outcomes. Bob on the other hand is looking for HH, that is only in HHH, THH, HHT, 3 out of 8 possible outcomes. So while HH and HT are equal in probability when you consider 2 coin flips, the combination of HT happens more often than HH. This is the case with 3 coin flips - there is no guarantee it translate to the same with more coin flips, but that is my bet.
Also the question "which substring occurs earlier on average" is intimately connected with algorithms for substring search. For example, if you want to check that a string doesn't contain HHH, you need to look at every third character, but for THH that's not enough.
Fascinating stuff.
Multiple heads in a row are more bunched than transition sequences because, for example, a sequence of three heads in a row will include two sequences with two heads in a row. You can't do that with a transition sequence--it takes at least four tosses to get two identical transition sequences.
We basically have four cases for Bob:
- HH: terminates for Bob.
- HT: Bob restarts the sequence.
- TT: Bob restarts the sequence.
- TH: This is a continuation. It degenerates into the answer to a single throw. Otherwise its just a recursion.
Then we have another four cases for Alice:
- HH: This is a continuation. It degenerates into the answer to a single throw or else a recursion.
- HT: terminates for Alice.
- TT: Alice restarts the sequence.
- TH: This is a continuation. It degenerates into the answer to a single throw. Otherwise its just a recursion.
So with that understanding it is a bit more clear how we get this result:
Alice has one win and two opportunities for a win and one for a restart. Bob has one win and one opportunity for a win and two restarts.
That was a bit confusing. I wonder how the problem could be worded to ensure that people got the answer correctly every time?
In the case of failure, Alice still has 50% chance of success in each subsequent toss. On average she will need two additional tosses to get a tail and the answer is 2+2=4.
In the case of failure, Bob has to start again. If we call the answer x, we can write x=2+0.5 1+0.5 (1+x) and solving the equation we get x=6.
A prime ending in 2 (in base 11) is also unlikely to be following by a prime ending in 5, 7 or 9, whereas it is particularly likely to be following by a prime ending in 4 or 8.
It would be interesting to know what structure there is (if any) in this NxN "transition matrix" for various bases.
1: ( 1, 4.3%) ( 2, 13.0%) ( 3, 14.3%) ( 4, 7.7%) ( 5, 11.5%) ( 6, 6.3%) ( 7, 18.0%) ( 8, 9.0%) ( 9, 10.7%) (10, 5.2%)
2: ( 1, 10.0%) ( 2, 3.7%) ( 3, 11.3%) ( 4, 14.1%) ( 5, 7.5%) ( 6, 12.1%) ( 7, 5.3%) ( 8, 17.5%) ( 9, 7.8%) (10, 10.7%)
3: ( 1, 6.1%) ( 2, 10.3%) ( 3, 3.7%) ( 4, 12.5%) ( 5, 14.0%) ( 6, 9.2%) ( 7, 12.1%) ( 8, 5.6%) ( 9, 17.5%) (10, 9.0%)
4: ( 1, 11.1%) ( 2, 6.1%) ( 3, 9.9%) ( 4, 4.1%) ( 5, 11.5%) ( 6, 14.5%) ( 7, 7.7%) ( 8, 12.0%) ( 9, 5.3%) (10, 18.0%)
5: ( 1, 9.6%) ( 2, 12.7%) ( 3, 6.3%) ( 4, 11.5%) ( 5, 4.0%) ( 6, 13.6%) ( 7, 14.5%) ( 8, 9.2%) ( 9, 12.1%) (10, 6.4%)
6: ( 1, 17.9%) ( 2, 8.5%) ( 3, 10.6%) ( 4, 5.0%) ( 5, 9.6%) ( 6, 4.0%) ( 7, 11.4%) ( 8, 14.0%) ( 9, 7.5%) (10, 11.5%)
7: ( 1, 6.0%) ( 2, 19.1%) ( 3, 8.8%) ( 4, 11.1%) ( 5, 5.1%) ( 6, 11.6%) ( 7, 4.1%) ( 8, 12.5%) ( 9, 14.1%) (10, 7.7%)
8: ( 1, 12.0%) ( 2, 5.5%) ( 3, 17.5%) ( 4, 8.8%) ( 5, 10.6%) ( 6, 6.3%) ( 7, 9.9%) ( 8, 3.7%) ( 9, 11.3%) (10, 14.3%)
9: ( 1, 8.8%) ( 2, 12.4%) ( 3, 5.5%) ( 4, 19.1%) ( 5, 8.6%) ( 6, 12.7%) ( 7, 6.0%) ( 8, 10.3%) ( 9, 3.7%) (10, 13.0%)
10: ( 1, 14.3%) ( 2, 8.8%) ( 3, 12.0%) ( 4, 6.0%) ( 5, 17.8%) ( 6, 9.6%) ( 7, 11.1%) ( 8, 6.1%) ( 9, 10.0%) (10, 4.3%)I take your point about primes being closely packed at low numbers, but I think this is a small correction (i.e. you might expect 8-9% of primes ending in 2 to be followed by another prime ending in 2, but certainly not <4%)
https://news.ycombinator.com/threads?id=crnt2
The result - the factor is actually surprisingly large!
I did my own investigation using base 3 and noticed something peculiar.
In the first 100k primes, we go from 1 to 2 29028 times and from 2 to 1 29029 times.
Then I filtered out the twin primes since those are the ones that exploit the fact that the next "possible" prime is one that flips the last digit.
This filtered out 10249 primes going from 2 to 1 (bringing the total below both the number of primes that stay at 2 (21008) and the number of primes that stay at 1 (20932)).
It didn't factor out any primes that go from 1 to 2. Are there no twin primes (p,p') where p%3 == 1 and p'%3 == 2?
edit: Oh hey, this is obvious, if p%3 is 1 then p+2 is divisible by 3. It does mean we don't need to take measurements to know that the result we are investigating cannot possibly account for everything since it isn't a factor at all when going from 1 to 2.
By definition, no there aren't. Twin primes are a distance of 2 apart, so your mod 3 options are 0 -> 2, 1 -> 0, and 2 -> 1. Anything involving 0 means it's divisible by 3, so your only mod 3 possibility for twin primes is 2 -> 1.
EDIT: Excluding the possibility where 3 mod 3 = 0, of course. This allows a 0 -> 2 transition with (3,5).
Edit: This basically works for base 10, too. I feel like the reason must either be very obvious or very deep.
1 3 7 9
1 0.0458 0.0746 0.0756 0.0540
3 0.0599 0.0439 0.0707 0.0755
7 0.0638 0.0677 0.0438 0.0747
9 0.0805 0.0638 0.0599 0.0458
It appears to have the same transition probabilities as in base 5 (with the two center rows and columns swapped): 1 2 3 4
1 0.0458 0.0756 0.0746 0.0540
2 0.0638 0.0438 0.0677 0.0747
3 0.0599 0.0707 0.0439 0.0755
4 0.0805 0.0599 0.0638 0.0458
I share your feeling about it being either obvious or deep.Well, yeah that's because 1,3,7,9 modulo 5 becomes 1,3,2,4 which is 1,2,3,4 with the centre two swapped.
As I've expressed in another comment, my preferred way of thinking about this symmetric pattern goes something like this:
The probability that (a prime congruent to x mod b is followed by a prime congruent to y mod b) seems to be equal to the probability that (a prime congruent to -y mod b is followed by a prime congruent to -x mod b).
I still haven't figured out whether it ought to be obvious, though if it is then I expect the language I've used above to be relevant. It's definitely not trivially obvious, because it's not an exact equality: if the pattern only shows up clearly after you've accumulated thousands or millions of primes, then it doesn't seem that it could be enforced by any sort of exact transformation. (For example, if the symmetric entries were somehow just counting the same pairs in two different ways, the numbers ought to be precisely equal rather than just increasingly close.)
There are a rather a lot of other patterns in the data; I expect that at least some of them must be accounted for in the original paper, but I haven't more than glanced through it yet.
"We can also show that c2(q; (a, b)) = c2(q; (−b,−a)) for any two reduced residue classes a and b (mod q)."
I'm not 100% certain this is responsible for the phenomenon that we're seeing, but it seems exceedingly likely. I think I'd need to stare at their formula for c2 for a long time to understand where this relation comes from, though.
Can't think of a trivial reason why that would be the case, something weird is happening.
Clearly, we should expect that for small primes (< 100e6) it is less likely that a prime ending in K (in base B) will be followed by another prime ending in K - because for that to happen, none of the B-1 numbers in between can be prime.
A (very naive) model of the distribution of primes says that every number n has probability p(n) = 1/log(n) of being prime. Assume that a number n ends with a k in base b. Define p = 1/log(n). Then the probability that the next prime ends in k+j is, roughly,
q(j) = p * (1-p)^(j-1) * sum_{i=0}^{infinity} (1-p)^(i*b)
= p * (1-p)^(j-1) / (1 - (1-p)^b)
In this formula, j takes values 1 to b (where j = b represents another prime ending in k).For n ~ 1,000,000 and working in base b, under this model we would expect to see around 6.97% of primes ending in k followed by another prime ending in k, whereas we expect to see 13.7% of primes ending in k+1 (it is apparent how naive the model is, since in fact we never see a prime ending in k followed by a prime ending in k+1, except for 2,3). It would not be hard to extend the model to rule out even primes, or multiples of 3 and 5, but I have not done this.
Around n ~ 10^60 the distribution starts to look more equal, as the primes are "spread out" enough that you expect to have long sequences of non-primes between the primes, which blurs out the distribution to be roughly constant.
I think this is what the article is getting at when it quotes James Maynard as saying "“It’s the rate at which they even out which is surprising to me". With a naive model of 'randomness' in the primes, you expect to see this phenomenon at low numbers (less then 10^60) and for it to slowly disappear at higher numbers. And indeed, you do see that, but the rate at which the phenomenon disappears is much slower than the random model predicts.
I think that is why it is surprising.
I don't think this is true at all. Take a look at the famous Ulam Spiral: http://scienceblogs.com/goodmath/wp-content/blogs.dir/476/fi...
You can see that while prime numbers are difficult to predict, they're anything but random. I'm not sure why the article is claiming that mathematicians used to think the distribution of primes was evenly distributed, which is complete and utter nonsense.
> We believe that the primes do not observe any significant pattern beyond the obvious ones (e.g. mostly being odd), but we are still a long way from making this belief completely rigorous.
That's from this set of slides on structure and randomness in the primes, which has some other relevant bits in it: https://terrytao.files.wordpress.com/2009/07/primes1.pdf
Especially relevant are slides 10-11 on treating the primes as a pseudorandom set, and then slides 14-15 on using pseudorandom models of the primes to rigorously (vs. heuristically) prove theorems. That's done by classifying and ruling out all possible ways nonrandom structure in the actual primes (the "conspiracies") could sink the specific theorem being proven.
I have a feeling that prime theory, and Ulam spirals in particular, will drive many mathematicians slightly crazy if they dwell on them too long.
On the other hand, they create wonderful patterns. I'm getting a laser-cut Ulam spiral done to hang on my wall :-)
Yeah, in practice it'll affect the total computation time, but generally security people tend to assume extremely generous fudge factors anyhow. A lot of times when you see security papers talking about how something takes "2 to the 50 operations", they're referring to the full process of hashing some string 2 to the 50 times or something like that, rather than 2 to the 50 CPU cycles. When so many security operations involve things getting exponentially harder as you add bits, there's not much point in trying to shave an order of magnitude here or there; you just go ahead and make things that are secure even if the entire universe is converted into computronium and dedicated to brute-forcing your security. (Because so far, that's never been the ultimate security problem.)
[1] https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Faulty_...
def primer():
p = 3
while True:
is_prime = True
for x in xrange(2, p):
if p % x == 0:
is_prime = False
break
if is_prime:
yield p
p += 2
give_prime = primer()
primes = [1, 2] # had to separate this into 2 lines because Python
primes.extend([give_prime.next() for x in xrange(9998)]) # so we get 10,000 primes
primes_dict = {}
for i in xrange(len(primes) - 1):
p0 = str(primes[i])[-1]
p1 = str(primes[i + 1])[-1]
key = "".join([p0, "-", p1])
try:
primes_dict[key] += 1
except:
primes_dict[key] = 1
# let's delete the 4 outliers from the begining
del(primes_dict["1-2"])
del(primes_dict["2-3"])
del(primes_dict["3-5"])
del(primes_dict["5-7"])
So long story short, my results over 10,000 primes: In [57]: primes_dict
Out[57]:
{'1-1': 365,
'1-3': 833,
'1-7': 889,
'1-9': 397,
'3-1': 529,
'3-3': 324,
'3-7': 754,
'3-9': 906,
'7-1': 655,
'7-3': 722,
'7-7': 323,
'7-9': 808,
'9-1': 935,
'9-3': 635,
'9-7': 541,
'9-9': 379}
And you can clearly see that the tendency to avoid the same last digit is starting to show, thow those that end in 1 are still not showing it completely. Tried with 100,000 primes but the (horrible) algorithm kinda got stuck so I settled with 10,000 to make this a "quick test".Before you go, please believe me I'm sorry for primer() and give_prime. I'll try to never do those kind of things again.
Edit: I've edited this like 5 times already over little typos and bad transcription mistakes I did all over the place. Should work now.
Thanks for pointing it out, I did this over an IPython session and copied it in a (completely unnecesary) hurry. The results are good though :)
Edit: as to keep my claim that the results are good, check this sentence from the article "...Nor could it explain why, as the pair found, primes ending in 3 seem to like being followed by primes ending in 9 more than 1 or 7." -- it backs up the data I posted :)
With just that change to your program, and asking for 100k primes:
{'9-1': 8829, '1-1': 4104, '9-7': 5671, '3-9': 8387, '3-7': 7419, '7-1': 6438, '1-3': 7961, '3-3': 3604, '7-9': 8022, '1-7': 8297, '7-3': 6928, '1-9': 4605, '3-1': 5596, '7-7': 3627, '9-3': 6513, '9-9': 3994}
use std::collections::HashMap;
pub fn first_n_primes(n: u64) -> Vec<u64> {
let mut primes = Vec::new();
let mut candidate = 3;
let mut count = 0;
if n >= 1 {
primes.push(2);
count += 1;
}
while count <= n {
let candidate_sqrt = ((candidate as f64).sqrt().ceil() + 1.0) as u64;
let mut is_prime: bool = true;
for prime in &primes {
if candidate % prime == 0 {
is_prime = false;
break;
}
if prime > &candidate_sqrt {
break;
}
}
if is_prime {
primes.push(candidate);
count += 1;
}
candidate += 2;
}
primes
}
fn main() {
let mut last_digit_pair_counts: HashMap<String, u64> = HashMap::new();
let primes = first_n_primes(1000000);
for i in 0..(primes.len() - 1) {
let last_digit0 = primes[i] % 10;
let last_digit1 = primes[i+1] % 10;
let digit_str = format!("{}-{}", last_digit0, last_digit1).to_string();
let counter = last_digit_pair_counts.entry(digit_str).or_insert(0);
*counter += 1;
}
last_digit_pair_counts.remove("2-3");
last_digit_pair_counts.remove("3-5");
last_digit_pair_counts.remove("5-7");
let mut ordered_keys: Vec<String> = last_digit_pair_counts.keys().cloned().collect();
ordered_keys.sort();
for key in &ordered_keys {
println!("{}: {}", key, last_digit_pair_counts[key]);
}
}
which outputs: 1-1: 42853
1-3: 77475
1-7: 79453
1-9: 50153
3-1: 58255
3-3: 39668
3-7: 72828
3-9: 79358
7-1: 64230
7-3: 68595
7-7: 39603
7-9: 77586
9-1: 84596
9-3: 64371
9-7: 58130
9-9: 428431. add fnv to your Cargo.toml's dependencies section 2. The first few lines become:
extern crate fnv;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use fnv::FnvHasher;
type MyHasher = BuildHasherDefault<FnvHasher>;
2. and the hash creation line becomes let mut last_digit_pair_counts: HashMap<String, u64, MyHasher> = HashMap::default();
This is 17% faster on my two runs of your code. :)Other notes:
format!("{}-{}", last_digit0, last_digit1).to_string();
The .to_string() is redundant here, format! already gives you a String. That should remove a bunch of allocations.Oh, one other thing: I noticed you said 20 seconds. Mine took about 4 seconds, and I was wondering where the difference was... did you compile with optimizations? Without, it takes 22s on my machine... `--release` as an argument to Cargo, or `-C opt-level=3` as an argument to rustc.
primes = {}
function inPrimes(n)
for _, v in ipairs(primes) do
if n%v == 0 then return false end
if v > math.ceil(math.sqrt(n)) then break end
end
return true
end
for i = 3, 1.6e7, 2 do
if inPrimes(i) then table.insert(primes, i) end
end
last = '7'
totalDigits = {}
for i = 4, #primes do
c = last..tostring(primes[i]):sub(-1)
totalDigits[c] = totalDigits[c] and totalDigits[c] + 1 or 1
last = c:sub(-1)
end
for k, v in pairs(totalDigits) do print(k, v) end
Gets just as many primes and runs in 7 seconds in LuaJIT. 79 3796948
37 3595468
19 2744958
97 3046626
31 3046813
71 3243702
93 3243354
33 2229686
11 2328414
73 3443707
99 2328896
17 3842263
39 3840531
77 2227956
13 3795751
91 4092457Could you try running both on the same machine? I'm curious if LuaJIT can still beat Rust if both have optimizations working.
I know it can beat native code sometimes, which is pretty impressive (it finds common cases and specializes to them AFAIK, almost like "sufficiently advanced optimizing compiler" fairy tales).
And of course, it takes 0 seconds to compile, if you factor in that time : )
3.67user 0.01system 0:03.68elapsed 99%CPU
rustc 1.9.0-nightly (74b886ab1 2016-03-13) (-C opt-level=3):
5.18user 0.00system 0:05.20elapsed 99%CPU
Switching to BTreeMap gives me:
4.36user 0.00system 0:04.38elapsed 99%CPU
Using u8 as the key (last_digit0*10 + last_digit1) instead of a string:
4.18user 0.00system 0:04.18elapsed 99%CPU
I tried preallocating the vector of primes and it didn't help, strangely enough.
Replacing the floating-point sqrt with squaring in the comparison does bring it a bit lower:
4.04user 0.00system 0:04.05elapsed 99%CPU
I don't know how to bring that number lower without using a sieve, perf reports that most of the time is spent in:
86,31 │ div %rbx
I've also just noticed that the Lua and the Rust code don't give the same results, but I can't easily tell why.
Oh! The largest prime is 0x00ec4bab, so they can be stored as u32. Final Rust result:
2.33user 0.00system 0:02.33elapsed 99%CPU
The Lua code is not exactly identical to the rust code. I test all numbers less than n, as opposed to counting n primes. I set n so it got slightly more primes than the rust code though.
import Data.Numbers.Primes
import Data.Counter
countPrimeTransitions n = count $ zip primeEndings (tail primeEndings)
where primeEndings = take (n+1) (map (`mod` 10) primes) my $primes := (1..*).grep(*.is-prime);
my %count;
for ^100000 -> $i {
%count{($primes[$i] % 10) ~ '-' ~ ($primes[$i+1] % 10)}++;
}
for %count.keys.sort -> $key {
say "$key = { %count{$key} }";
}
(I didn't skip the outliers, but I did explicitly write out the count so that it was in order.)Results from the first 100,000 primes:
1-1 = 4104
1-3 = 7961
1-7 = 8297
1-9 = 4605
2-3 = 1
3-1 = 5596
3-3 = 3604
3-5 = 1
3-7 = 7419
3-9 = 8387
5-7 = 1
7-1 = 6438
7-3 = 6928
7-7 = 3627
7-9 = 8022
9-1 = 8830
9-3 = 6513
9-7 = 5671
9-9 = 3995 my %count := (1..*).grep(*.is-prime).map(* % 10).rotor(2 => -1).map(~*)[^100000].Bag;
I think it's a bit slower than my previous version. (And much slower than the Rust version posted elsewhere here!)Primes are the simplest way to encode specific kinds of graphs that unambiguously encodes all sub-graphs.
If you try to come up with a bit-representation that is equivalently rich it becomes difficult to think of one that is as simple yet preserves the semantics of the factorization tree.
So I guess my point is that the factorization tree of numbers is the fundamental concept, and it's information theoretic. Primes happen to be an encoding of that fundamental concept into integers, but if we found an equivalently rich representation using a different encoding, we might understand primes better. I doubt that the quirks of the encoding has anything to do with the fundamental concept however.
Symbolic regression basically uses genetic algorithms to fit mathematical expressions to data. The program I was using, Eureqa, tries to find the simplest expressions that fit, with only a handful of elements. To prevent overfitting, and give a human understandable model.
Anyway this actually worked. Far from perfectly of course, but it was able to get much better than random predictions. It was definitely finding some pattern.
Unfortunately I used up Eureqas free trial forever ago, and I'm not going to pay thousands of dollars to buy a subscription. But I am now thinking of writing my own software to do this, and then running it on a dataset of mathematical sequences like the primes.
cumulative:
1 to 1: 30768 rand, 28289 prime
1 to 3: 53573 rand, 51569 prime
1 to 7: 44306 rand, 53263 prime
1 to 9: 36968 rand, 32816 prime
ratios:
1 to 1: 0.18578027352594872 rand, 0.17048036302934247 prime
1 to 3: 0.323479153458322 rand, 0.3107745710721539 prime
1 to 7: 0.26752407692539926 rand, 0.3209832647330011 prime
1 to 9: 0.22321649609032998 rand, 0.19776180116550257 prime
cumulative:
3 to 1: 37015 rand, 38455 prime
3 to 3: 31015 rand, 25900 prime
3 to 7: 53377 rand, 48596 prime
3 to 9: 44594 rand, 53082 prime
ratios:
3 to 1: 0.22298058445431052 rand, 0.23161058343823215 prime
3 to 3: 0.18683622387816942 rand, 0.15599308571187656 prime
3 to 7: 0.3215462557454473 rand, 0.2926888028283534 prime
3 to 9: 0.2686369359220728 rand, 0.3197075280215379 prime
cumulative:
7 to 1: 44412 rand, 42590 prime
7 to 3: 36923 rand, 45728 prime
7 to 7: 30588 rand, 25886 prime
7 to 9: 53404 rand, 51800 prime
ratios:
7 to 1: 0.26863125805222376 rand, 0.25656008288956894 prime
7 to 3: 0.2233331518747694 rand, 0.275463241849594 prime
7 to 7: 0.18501515179008873 rand, 0.15593600154213152 prime
7 to 9: 0.3230204382829181 rand, 0.3120406737187056 prime
cumulative:
9 to 1: 53453 rand, 56602 prime
9 to 3: 44489 rand, 42837 prime
9 to 7: 37022 rand, 38259 prime
9 to 9: 30902 rand, 28144 prime
ratios:
9 to 1: 0.322266166664657 rand, 0.3413007561413876 prime
9 to 3: 0.2682225410873838 rand, 0.2583000687401261 prime
9 to 7: 0.22320427332907286 rand, 0.23069548124118136 prime
9 to 9: 0.18630701891888632 rand, 0.1697036938773049 prime
Unless I'm doing something wrong, it honestly it doesn't seem like the actual prime numbers have a statistic that deviates from random numbers with a prime distribution. Hence it looks like to me just the result of a) specifying the "next" number which naturally favors the digit after it and b) probability of a given number being prime (prime number theorem).I wonder if this is really an artifact like Benford's Law, which also involves first-digit-frequency (in any base) and also involves certain kinds of "random" numbers.
To recycle a past comment:
> If you have a random starting value (X) multiplied by a second random factor (Y), most of the time the result will start with a one.
> You're basically throwing darts at logarithmic graph paper! The area covered by squares which "start with 1" is larger than the area covered by square which "start with 9".
[1] https://en.wikipedia.org/wiki/Prime_number_theorem
[2] https://en.wikipedia.org/wiki/Benford%27s_law#Multiplicative...
Unless the random number generator was flawed of course, but that's a different issue.
f[n_, base_] :=
Module[
{m, d, dpairs},
d = Table[Last[IntegerDigits[Prime[i], base]], {i, 1, n}];
dpairs = Table[{d[[i]], d[[i + 1]]}, {i, 1, Length[d] - 1}];
Map[#[[1]] -> #[[2]] &, Tally[dpairs]]
]
For the first n primes in a given base, it returns the mapping {i,j}->count for the all pairings of digit i followed by digit j. E.g., for the first million base 5 primes {2, 3} -> 68596
{3, 0} -> 1,
{0, 2} -> 1,
{2, 1} -> 64230
{1, 3} -> 77475
{3, 2} -> 72827
{2, 4} -> 77586
{4, 3} -> 64371
{3, 4} -> 79358
{4, 1} -> 84596
{1, 2} -> 79453
{4, 2} -> 58130
{4, 4} -> 42843
{1, 1} -> 42853
{3, 3} -> 39668
{2, 2} -> 39603
{1, 4} -> 50153
{3, 1} -> 58255I guess the author wanted to avoid discussing modular arithmetic in an article for general audiences?
Now that is particularly interesting to think about.
Multiple heads in a row are more bunched than transition sequences because, for example, a sequence of three heads in a row will include two sequences with two heads in a row. You can't do that with a transition sequence--it takes at least four tosses to get two identical transition sequences.
A while back, I read something about different number bases' ability to help find additional primes. The base itself was prime, so maybe 7 or 13. Can't find the article ATM. I hypothesized that prime numbers are "code" provided by this universe to allow us to access other data stored in other primes. Quines of a sort, if you will. One way to invalidate this hypothesis would be to do a mean distribution of basic operators in a simple programing language and compare it to what we are seeing in primes.
(I don't mean to nitpick - I'm genuinely curious. I recall seeing the same thing in high-school chemistry, but never in physics, for example, and I'm curious if entire fields see this effect or if it's a product only of the audience being written to).
Counter-intuitive at first but makes sense - the outcomes as a whole converge towards the average (50% heads, 50% tails). Nonetheless, it shows that each toss is related to the others. One can expect that primes are even more related - or at least to the primes that came before.
The reason HT is likely to occur quicker is: after a failed win, HH needs two flips to win (1/4 chance), but HT can win in just one flip (1/2 chance).
Just based on this knowledge, I know that a prime number is guaranteed not to be immediately followed by another one with the same ending 1 time in 2.
I'm not sure these fellows have found anything particularly interesting, but if so, and I have missed something, kudos to them.
Does a prediction based on base 3 hold up better over primes under 100 than 1000 and 1000 than 10000?
Is the ratio of how well a base ending sequence is predictive scale to a predictable range based on the base that the prime number field is viewed within?
Just thinking about what might be happening, I would imagine that the answer is yes, but that a lot of crunching would be needed to graph and deduce a relationship to an actual predictive property statement.
Because 100x will become >200 "slower" than 200x becomes >300 etc. With slower meaning lower value of x. x in this case is usually a random variable centered around 1.
I have a premonition of Quite a Bit of Trouble coming down the pipe.
I HAD THE EXACT SAME IDEA. But I would probably have reached no conclusion.
23=(7)3+(2);
7=(2)3+(1);
2=(0)3+(2);
0=(0)3+(0);
Take only remainders, and form a vector a=(2 1 2 0) What can be said about components of the vector for the prime next to p? E.g., do i-th components repel, like the 1-st ones?
If we had 8 fingers would we have notice something similar. Would it be even stronger.
If we used base 60 would it even be there?
-Traruh
Clearly, not for base 2.
How about base 816 or 60? How about the unpopular odd numbered bases?
This is how modern computers revolutionized even the most theoretical fields like number theory. Remarkable, I love it!
I don't understand.
But it's a great result, so I've upvoted it, despite being confused.
If that fails, you an email the mods hn@ycombinator.com . If this has an easy explanation, usually dang answer in the same day.
Zim + Teemo for Quanta Magazine By: Erica Klarreich March 13, 2016 Comments (2)
Share this:facebooktwitterredditmail PDFPrint Two mathematicians have uncovered a simple, previously unnoticed property of prime numbers — those numbers that are divisible only by 1 and themselves. Prime numbers, it seems, have decided preferences about the final digits of the primes that immediately follow them.
Among the first billion prime numbers, for instance, a prime ending in 9 is almost 65 percent more likely to be followed by a prime ending in 1 than another prime ending in 9. In a paper posted online today, Kannan Soundararajan and Robert Lemke Oliver of Stanford University present both numerical and theoretical evidence that prime numbers repel other would-be primes that end in the same digit, and have varied predilections for being followed by primes ending in the other possible final digits.
“We’ve been studying primes for a long time, and no one spotted this before,” said Andrew Granville, a number theorist at the University of Montreal and University College London. “It’s crazy.”
The discovery is the exact opposite of what most mathematicians would have predicted, said Ken Ono, a number theorist at Emory University in Atlanta. When he first heard the news, he said, “I was floored. I thought, ‘For sure, your program’s not working.’”
This conspiracy among prime numbers seems, at first glance, to violate a longstanding assumption in number theory: that prime numbers behave much like random numbers. Most mathematicians would have assumed, Granville and Ono agreed, that a prime should have an equal chance of being followed by a prime ending in 1, 3, 7 or 9 (the four possible endings for all prime numbers except 2 and 5).
“I can’t believe anyone in the world would have guessed this,” Granville said. Even after having seen Lemke Oliver and Soundararajan’s analysis of their phenomenon, he said, “it still seems like a strange thing.”
Yet the pair’s work doesn’t upend the notion that primes behave randomly so much as point to how subtle their particular mix of randomness and order is. “Can we redefine what ‘random’ means in this context so that once again, [this phenomenon] looks like it might be random?” Soundararajan said. “That’s what we think we’ve done.”
Prime Preferences
Soundararajan was drawn to study consecutive primes after hearing a lecture at Stanford by the mathematician Tadashi Tokieda, of the University of Cambridge, in which he mentioned a counterintuitive property of coin-tossing: If Alice tosses a coin until she sees a head followed by a tail, and Bob tosses a coin until he sees two heads in a row, then on average, Alice will require four tosses while Bob will require six tosses (try this at home!), even though head-tail and head-head have an equal chance of appearing after two coin tosses.
Can someone explain this?
Say, there is a fixed and equal probability that each number ending with 9 and 1 is prime. I could go along with that assumption, although the fact that primes get less likely as you go higher is potentially relevant.
What the authors consider here is starting with a prime ending in 9. So the next potential prime ends in 1. If only because 1 is the next number to be checked, a 1-prime is more likely to appear next than a 9-prime. The probability of that can be calculated, depending on your assumptions, as a geometric sequence. In any case, P(next prime is 1) > P(next prime is 9).
"Most mathematicians would have assumed, Granville and Ono agreed, that a [known] prime should have an equal chance of being followed by a prime ending in 1, 3, 7 or 9" So - I'm a definite nope on that.
This result appears to be exactly what I would have assumed was the case.
> Lemke Oliver and Soundararajan’s first guess for why this bias occurs was a simple one: Maybe a prime ending in 3, say, is more likely to be followed by a prime ending in 7, 9 or 1 merely because it encounters numbers with those endings before it reaches another number ending in 3. For example, 43 is followed by 47, 49 and 51 before it hits 53, and one of those numbers, 47, is prime.
> But the pair of mathematicians soon realized that this potential explanation couldn’t account for the magnitude of the biases they found. Nor could it explain why, as the pair found, primes ending in 3 seem to like being followed by primes ending in 9 more than 1 or 7.
> The primes' preferences about the final digits of the primes that follow them can be explained, Soundararajan and Lemke Oliver found, using a much more refined model of randomness in primes, something called the prime k-tuples conjecture.
So I guess that my observation is just a special case of this "prime k-tuples conjecture".
It's amazing how people can be picky and negative on HN. Someone positive would instead congratulate me for making the gist of what the prime k-tuple conjecture says about the biases easily understandable. Oh well.
The top comment here on HN does not recognise the 'trivial' point that I have made, hence the need to point it out.
And, the "most mathematicians would have assumed..." quote is probably false.