A perlmonk asked for a “custom random number generator”. This is a non-maths person’s word for a probability distribution.

It was a slightly unusual case, but not hard. After I’d finished several easy steps, though, the final formula looked like it had been **scrivened by a wizard:**

Of course, I’m not a wizard; I’m not even an acolyte. The steps I took just involved (1) a certain viewpoint on probability distributions, and (2) puzzles that an 11-year-old could solve.

*This is how formulas in textbooks get to look so daunting.*

—skippable interlude—

I guess I figured this out years ago, when I first saw the Black-Scholes-Merton formula in business school.

The BSM is just a continuous-time limit of “Did the stock go up or down in the last 5 minutes?” But the BSM is dressed up with such frightening language that it seems much more inscrutable than “A tree generated from two alternatives which are repeated”.

For example in the Wikipedia article on BSM the subheads include: Greeks (∂), elliptic PDE’s, derivation, interpretation, criticism, extensions of the model, notation, assumptions, references. It’s 24 pagedowns long. From this **pretence of sophistication** follows:

I’ve seen it in biology, chemistry, and physics textbooks as well. A convoluted formula encodes the results of a simple model. Because of scientism the students commit it to memory as well as more derived results. Hopefully they come to find that it was *not* so complicated only a professors could understand it.

But I don’t think that’s common knowledge, so formulæ retain an impenetrable mysticism and the rituals of uncomprehending repetition continue.

—back to the main idea—

It needn’t be so enigmatic. I can demonstrate that by showing how the ugly beast above looks if you break it into steps. It’s simpler as several lines of code than as one formula.

**Client Request**

Anonymous Monk wanted a probability distribution like this:

with the median at **x** and equal probability masses between `[x/y,x]`

and `[x, x•y]`

**Drawrings**

I’m going to take a Gaussian and map the endpoints to what the client wants.

The result will tend to the centre a “normal” amount of the time and yet will be squashed onto the domain the client wants.

**Match up the Endpoints**

I know that **exp** maps `(−∞,0]`

onto `(0,1]`

.

To follow that, I need a transformation that will match `(0,1)`

to `(x/y, x)`

. So `1 ⟼ x`

and `0 ⟼ x/y`

.

`0 ⟼ x`

and `1 ⟼ xy`

**as 6 lines of Code**

my $random = ...; #Gaussians, however you fry them up
if ($random <= 0) {
$random = exp($random); #map (−∞,0) → (0,1)
$random = ; #map (0,1) → (x, x•y)
}
else { #map (0, +∞) → (0,1)
$random = 1 − exp(−$random); #map (0, +∞) → (0,1) ... which is the same problem as above except backwards
$random = ; #map (0,1) → (x/y, x)

**Lessons:**

- use paper
*first*, write code second
- draw a picture
- if necessary, break it into a simpler picture
- compose
**∘** the answers to the parts
- code the pieces in separate lines

The equation at the top does decompose into the sequence of steps I just outlined. But even though it looks simple as a sequence of steps, the one-line formula is scary.