John D. Cook

https://www.johndcook.com/blog

226 posts · 22 Votes · 1 Followers

Science 51% · Tech 38% · Writing 5% · Culture 3% · Life 1% · Art 0% · 2 more 2%

Subscribe via RSS

  1. Subscribe by email

    Readers have subscribed to this blog via email almost from its beginning in 2008, but how they have subscribed has changed several times. I’ve used several services to provide email subscription that have come and gone. For the past two years I’ve been using Substack to send out emails announcing new blog posts. That has worked out well. Substack delivers email reliably, and that’s all I wanted. I’m not active on Substack other than using it to an email. I give a brief introduction to the…

    0 ▲
  2. Another Gaussian approximation

    The function (1 + cos(x))/2 gives a fair approximation to the Gaussian density exp(−x²) You can make the approximation much better by raising it to a power. The function ((1 + cos(x))/2)4 gives a good lower bound and ((1 + cos(x))/2)3.5597 gives a good upper bound. More on that here. There are other ways of improving the cosine approximation to the Gaussian. Yesterday I came across one I hadn’t seen before, adding a sin(x) term to x. (1 + cos(sin(x) + x))/2 This function matches the first few…

    0 ▲
  3. Spot checking polynomial identities

    If a polynomial identity holds at a few random points, it’s very like true. We’ll make this statement more precise, but first let’s look at some applications. You may want to test an identity that naturally presents itself as a statement that two polynomials are equal. Or you might use something like the binomial coefficient trick to reframe a problem isn’t obviously an identity about polynomials. And with algebraic circuits, you can reformulate a wide range of computations as polynomial…

    0 ▲
  4. Online (one-pass) algorithms

    Canonical example The variance of a set of numbers is defined as the sum of the squared distances from each point to the mean. So it would seem that you first need to calculate the mean, then go back and compute the squared differences from the mean. And yet the variance can be computed in one pass through the data. You’ll find two equivalent equations in statistics books: the one described above and another based on the sum of the data points and the sum of the data points squared. While this…

    0 ▲
  5. Turning K-L divergence into a metric

    Kullback-Leibler divergence Kullback-Leibler divergence is defined for two random variables X and Y by K-L divergence is non-negative, and it’s zero if and only if X and Y have the same distribution. But it is not a metric, for reasons explained here. For one thing, it’s not symmetric. Jeffreys divergence We can fix the symmetry problem by defining The J above stands for Jeffreys, for Harold Jeffreys. J is called either the symmetrized K-L divergence or Jeffreys’ divergence. It’s still a…

    0 ▲
  6. The Meta logo and fitting Besace curves

    I saw a post yesterday saying that the Meta logo is a Besace curve. A Besace curve has the implicit form and the parametric form where t ranges over [0, 2π]. So given a Besace curve, such as the Meta logo, how do you find the parameters a and b to fit the curve? We can rewrite the parametric expression for x as a sine with a phase shift (see notes here) where Also, we can rewrite the parametric expression for y as Now the extreme values of x and y are easier to see. The maximum value of x is A…

    0 ▲
  7. Calculating the expected range of normal samples

    The previous post looked at the expected IQ range in a jury of 12. This post will look more generally at computing the expected range of n samples from a N(0, 1) random variable. This will give the expected range in units of σ, i.e. multiply the results by σ if your σ isn’t 1. As mentioned in the previous post, the expected range is given by where φ and Φ are the PDF and CDF of a standard normal. The integral can be calculated in closed form for n ≤ 5, but in general it requires numerical…

    0 ▲
  8. Expected IQ spread on a jury

    There’s been some discussion online lately about how a large difference in IQ makes it difficult for two people to communicate. There have been studies that confirm this effect. The difficulty is not insurmountable, but it takes deliberate effort to overcome. Someone dismissed this communication difficulty by pointing out that the expected difference in IQ between two individuals is around 17, suggesting that most communication is between people who differ by more than one standard deviation in…

    0 ▲
  9. Hilbert transform as an infinite matrix

    The previous post linked to a post I wrote a few years ago about the Hilbert transform and Fourier series. That post says that if the Fourier series of a function is then the Fourier series of its Hilbert transform is When I looked back at that post I thought about how if you thought of the Fourier coefficients as elements of an infinite vector then the Hilbert transform can be represented as multiplying by an infinite block matrix. I rarely see infinite matrices except in older math books.…

    0 ▲
  10. Real and imaginary parts

    The previous post announced some notes I wrote up based on an article by Henry Baker implementing functions of a complex variable in terms of functions of a real variable. That is, it finds functions u(x, y) and v(x, y) such that f(x + iy) = u(x, y) + i v(x, y) where x, y, u, and v are all real-valued. Not only that, but if f is an elementary function, so are u and v. Here “elementary” has a technical meaning, but essentially it means functions that you could evaluate on a scientific…

    0 ▲
  11. Building complex functions out of real parts

    A couple months ago I wrote about how to compute the sine and cosine of a complex number using only real functions of real variables using the equations You can do something analogous for all the elementary functions, though some of the equations are quite a bit more complicated than the ones above. See the equations here. The equations come from a paper by Henry G. Baker, cited in the linked page. I wrote up Baker’s equations in LaTeX, then used ChatGPT to generate Python code from the LaTeX…

    0 ▲
  12. Couth and uncouth function pairs

    “You can’t always get what you want. But sometimes you get what you need.” — The Rolling Stones Circular functions and hyperbolic functions aren’t invertible, but we invert them anyway. These functions map many points in the domain to each point in the range, and we invert them by mapping a point in the range back to some point in the domain. Often this works as expected, but sometimes it doesn’t. In the previous post I said You can relate each trig function “foo” with its hyperbolic…

    0 ▲
  13. Circular and hyperbolic functions differ by rotations

    The difference between a circular function and a hyperbolic function is a rotation or two. For example, cosh(z) = cos(iz). You can read that as saying that to find the hyperbolic cosine of z, first you rotate z a quarter turn to the left (i.e. multiply by i) and then take the cosine. For another example, sinh(z) = −i sin(iz). This says that you can calculate the hyperbolic sine of z by rotating z to the left, taking the sine, and then rotating to the right. You can relate each trig function…

    0 ▲
  14. Square root of x² − 1

    How should we define √(z² − 1)? Well, you could square z, subtract 1, and take the square root. What else would you do?! The question turns out to be more subtle than it looks. When x is a non-negative real number, √x is defined to be the non-negative real number whose square is x. When x is a complex number √x is defined to be a function that extends √x from the real line to the complex plane by analytic continuation. But we can’t extend √x as an analytic function to the entire complex plane…

    0 ▲
  15. Closer look at an identity

    The previous post derived the identity and said in a footnote that the identity holds at least for x > 1 and y > 1. That’s true, but let’s see why the footnote is necessary. Let’s have Mathematica plot The plot will be 0 where the identity above holds. The plot is indeed flat for x > 1 and y > 1, and more, but not everywhere. If we combine the two square roots and plot again we still get a valid identity for x > 1 and y > 1, but the plot changes. This is because √a √b does not necessarily equal…

    0 ▲
  16. Approximating Markov’s equation

    Markov numbers are integer solutions to x² + y² + z² = 3xyz. The Wikipedia article on Markov numbers mentions that Don Zagier studied Markov numbers by looking the approximating equation x² + y² + z² = 3xyz + 4/9 which is equivalent to f(x) + f(y) = f(z) where f(t) is defined as arccosh(3t/2). It wasn’t clear to me why the two previous equations are equivalent, so I’m writing this post to show that they are equivalent. Examples Before showing the equivalence of Zagier’s two equations, let’s…

    0 ▲
  17. Recovering the state of xorshift128

    I’ve written a couple posts lately about reverse engineering the internal state of a random number generator, first Mersenne Twister then lehmer64. This post will look at xorshift128, implemented below. import random # Seed the generator state a: int = random.getrandbits(32) b: int = random.getrandbits(32) c: int = random.getrandbits(32) d: int = random.getrandbits(32) MASK = 0xFFFFFFFF def xorshift128() -> int: global a, b, c, d t = d s = a t ^= (t << 11) & MASK t ^= (t >> 8) & MASK s ^= (s >>…

    0 ▲
  18. Initialize and print 128-bit integers in C

    If you look very closely at my previous post, you’ll notice that I initialize a 128-bit integer with a 64-bit value. The 128-bit unsigned integer represents the internal state of a random number generator. Why not initialize it to a 128-bit value? I was trying to keep the code simple. A surprising feature of C compilers, at least of GCC and Clang, is that you cannot initialize a 128-bit integer to a 128-bit integer literal. You can’t directly print a 128-bit integer either, which is why the…

    0 ▲
  19. Hacking the lehmer64 RNG

    A couple days ago I wrote about hacking the Mersenne Twister. I explained how to recover the random number generator’s internal state from a stream of 640 outputs. This post will do something similar with the lehmer64 random number generator. This generator is very simple to implement. Daniel Lemire found it to be “the fastest conventional random number generator that can pass Big Crush,” a well-respected test for pseudorandom number generators. Implementing lehmer64 The lehmer64 generator can…

    1 ▲
  20. Euler function

    This morning I wrote a post about the probability that a random matrix over a finite field is invertible. If the field has q elements and the matrix has dimensions n × n then the probability is In that post I made observation that p(q, n) converges very quickly as a function of n [1]. One way to see that the convergence is quick is to note that and John Baez pointed out in the comments that p(q, ∞) = φ(1/q) where φ is the Euler function. Euler was extremely prolific, and many things are named…

    0 ▲
  21. Inverse shift

    What is the inverse of shifting a sequence to the right? Shifting it to the left, obviously. But wait a minute. Suppose you have a sequence of eight bits abcdefgh and you shift it to the right. You get 0abcdefg. If you shift this sequence to the left you get abcdefg0 You can’t recover the last element h because the right-shift destroyed information about h. A left-shift doesn’t fully recover a right-shift, and yet surely left shift and right shift are in some sense inverses. Yesterday I wrote a…

    0 ▲
  22. Probability that a random binary matrix is invertible

    The two latest posts have involved invertible matrices with 0 and 1 entries. If you fill an n × n matrix with 0s and 1s randomly, how likely is it to be invertible? What kind of inverse? There are a couple ways to find the probability that a binary matrix is invertible, depending on what you mean by the inverse. Suppose you have a matrix M filled with 0s and 1s and you’re looking for a matrix N such that MN is the identity matrix. Do you want the entries of N to also be 0s and 1s? And when you…

    0 ▲
  23. The linear algebra of bit twiddling

    The previous post looked at the tempering step of the Mersenne Twister, formulating a sequence of bit operations as multiplication by a matrix mod 2. This post will look at the components more closely. The theorems of linear algebra generally hold independent of the field of scalars. Typically the field is ℝ or ℂ, but most of basic linear algebra works the same over every field [1]. In particular, we can do linear algebra over a finite field, and we’re interested in the most finite of finite…

    0 ▲
  24. Reverse engineering Mersenne Twister with Linear Algebra

    The Mersenne Twister (MT) is a random number generator with good statistical properties but bad cryptographic properties. In buzzwords, it’s a PRNG but not a CSPRNG. This post will show how the internal state of a MT generator can be recovered from its output. We’ll do this using linear algebra. The bit twiddling approach is more common and more efficient, but the linear algebra approach is conceptually simpler. How MT works There are numerous variations on the Mersenne Twister. We’ll focus on…

    0 ▲
  25. Calculating curvature

    Curvature is conceptually simple but usually difficult to calculate. For a level set curve f(x, y) = c, such as in the previous couple posts, the equation for curvature is Even when f has a fairly simple expression, the expression for κ can be complicated. If we define then the level set of f(x, y) = c is an equilateral triangle when c = −4. The level sets are smoothed triangles for −4 < c < 0. The curvature of these level sets at any point is given by Simplification But there is one instance…

    0 ▲
  26. Smoothed polygons

    The previous post constructed a triangular analog of the squircle, the unit circle in the p-norm where p is typically around 4. The case p = 2 is a Euclidean circle and the limit as p → ∞ is a Euclidean square. The previous post introduced three functions Li(x, y) such the level set of each function forms a side of a triangle. Then it introduced a soft penalty for each L being away 1, and the level sets of that penalty function formed the rounded triangles we were looking for. Another approach…

    0 ▲
  27. Triangular analog of the squircle

    TimF left a comment on my guitar pick post saying the image was a “squircle-ish analog for an isosceles triangle.” That made me wonder what a more direct analog of the squircle might be for a triangle. A squircle is not exactly a square with rounded corners. The sides are continuously curved, but curved most at the corners. See, for example, this post. Suppose the sides of our triangle are given by L1(x, y) = 1 for i = 1, 2, 3. For example, We design a function f(x, y) as a soft penalty for…

    0 ▲
  28. Unified config files

    I try to maintain a consistent work environment across computers that I use. The computers differ for important reasons, but I’d rather they not differ for unimportant reasons. Unified keys One thing I do is remap keys so that the same key does the same thing everywhere, to the extent that’s practical. This requires remapping keys. In particular, I want the key functionality, not the key name, to be the same across operating systems. For example, the Command key on a Mac does what the Control…

    0 ▲
  29. The mythology of category theory

    Yesterday a friend and I had a conversation about category theory, how it can be a useful pattern description language, but also about how people have unrealistic expectations for it, believing category theory can deliver something for nothing. Later I ran across the following post from Qiaochu Yuan. It felt as if he had overheard my conversation and summarized it in a tweet: category theory is just some straightforwardly useful stuff for some purposes in some fields! you can elegantly simplify…

    0 ▲
  30. Changing one character in a PDF

    I saw a post on X saying Changing a hyphen to an en-dash increases your PDF file size by ~10 bytes. My first thought was that it had something to do with hyphen being an ASCII character and an en-dash not. Changing a hyphen to an en-dash would make a UTF-8 encoded text file a couple bytes longer. (See why here.) Maybe adding one non-ASCII character could cause the file to include a glyph it didn’t before. I did a couple experiments. I made a minimal LaTeX file with only the text See pages 9-10.…

    0 ▲