computational reproducibility
Imagine reading a paper with a striking computed result, downloading the authors' code and data, running it on your own machine, and getting exactly the same numbers. That experience — and the discipline that makes it possible — is computational reproducibility. It is the principle that a computational result should not be a one-off lucky run on one person's laptop, but something anyone can re-derive from the recorded ingredients. In a field where every numerical answer is approximate, being able to re-create exactly how an answer was produced is a cornerstone of taking it seriously as science.
It helps to separate two related words. REPRODUCIBILITY usually means: given the SAME code, data, and parameters, you get the same result — this is about provenance and bit-for-bit (or close-enough) repeatability of one specific computation. REPLICABILITY usually means the stronger thing: an INDEPENDENT team, with their own code, reaches the same scientific conclusion — this tests the finding, not just the run. Achieving reproducibility in practice means recording every ingredient: the exact source code (under version control, with a commit hash), the exact data and parameters, the software versions and dependencies (captured by a container or an environment file), and the random seeds, so that pseudorandom draws can be replayed exactly. Literate notebooks that interleave code, results, and explanation, plus open data and open code, make the whole chain inspectable.
Why this is hard, honestly, is worth stating. Floating-point arithmetic is the enemy of naive bit-for-bit reproducibility: floating-point addition is not associative, so summing the same numbers in a different order — which happens when parallel threads finish in a different sequence, or a library updates its blocking strategy — can change the last few digits. A different compiler, a different BLAS, a different number of cores, or fused multiply-add instructions can all shift results slightly. So 'reproducible to the last bit' is a demanding goal often reserved for regression tests, while 'reproducible to within a stated tolerance' is the more honest everyday standard. The misconception to avoid: reproducibility does not certify that a result is CORRECT — a reproducibly-wrong computation is still wrong — it certifies that the result is what the recorded recipe produces, which is the precondition for anyone to check, debug, or build on it.
A reproducible project ships: a git repository pinned to commit a1b2c3d, a Dockerfile or environment.yml fixing NumPy 1.26 and a specific BLAS, the input data with a checksum, a config file listing every parameter, and the line numpy.random.seed(42) so the Monte Carlo draws repeat. A reader runs one command and obtains the paper's figures. Change the seed or the BLAS, and the last digits may differ — which is why a tolerance, not exact equality, is checked.
Version-pinned code, fixed environment, recorded parameters, and a seeded RNG make a run re-derivable.
Reproducible does not mean correct: a reproducibly-wrong result is still wrong. And exact bit-for-bit repeatability is often unattainable because floating-point addition is not associative — a different core count or BLAS can shift the last digits, so a tolerance is the honest target.