Every Global25 admixture percentage you have ever seen — in Vahaduo, in our calculators, in a decade of forum arguments — descends from one R script. Ger Huijbregts wrote nMonte in the mid-2010s, the Eurogenes blog adopted it as the standard companion to its coordinate sheets, and its core idea has been reimplemented so many times that "nMonte-style" is now simply the name of the method. This is what the script actually does, and what it deliberately does not.
The problem it solves#
Given a target row and a set of source rows in the same coordinate space, find non-negative percentages summing to 100% whose weighted average of the sources lands as close to the target as possible. That is a constrained least-squares problem, and nMonte solves it the pragmatic way: Monte-Carlo descent. Start from some allocation of weight across sources; repeatedly propose a small random reallocation (move a slice of weight from one source to another); keep the proposal if the mixture's Euclidean distance to the target shrinks; stop when proposals stop helping. The final allocation is the breakdown, and the residual gap is the fit distance.
Randomised descent has two properties worth knowing. It handles any panel size without matrix algebra, which is why it ports so easily to browsers. And it is a local search: with near-collinear sources, different random runs settle on different splits of the shared signal — same fit, different story. When two sources trade ten points between runs, the instability is information: the panel, not the arithmetic, cannot tell them apart.
nMonte versus nMonte3, and the dials#
The original script fits the target as pasted. nMonte3 added the option everyone now argues
about: a penalty term (pen) that trades a slightly worse fit for a sparser, less scattered
model, damping the script's tendency to sprinkle 1–2% across many sources. Batch mode, "1 outcome
per line" runs and sheet conventions accumulated around it. Every dial is a modelling choice:
penalty on and off can move percentages by real amounts with near-identical fits — which is not a
bug but the method telling you those models are not distinguishable by distance alone.
Our production engine is a seeded descendant of the same family, with the choices fixed and stated: 500 weight slots (0.2% granularity), five independent restarts, pruning of sub-1.5% components followed by re-solving, a hard cap of eight sources, and a deterministic seed so a published result reproduces byte for byte. None of that changes the mathematics; it changes whether two people running "the same model" get the same answer.
What the script never enforces#
nMonte computes exactly what you asked and nothing about whether the question was sound. The discipline lives outside the script, and forgetting that is the whole failure mode of the genre:
- Scaled and unscaled rows must never mix — the script fits either happily, meaningfully fits neither mixed.
- Sources decide the answer. Any panel returns percentages; only panel construction decides whether they mean anything.
- Fit distance is not a p-value. Adding sources lowers it mechanically; a lower fit is not a better model past the point where the panel stays defensible.
- No rejection exists. A coordinate fit cannot fail. The method that can — qpAdm — works from allele-frequency statistics, not coordinates, and that difference is what the paid formal analysis buys.
Do you need to run the R script?#
Only if you want the dials or scriptable batch runs. For everything else the browser
implementations are the same mathematics with the bookkeeping handled:
Vahaduo for bring-your-own-sheet freedom, our
free calculators for curated era-scoped panels with the fit stated — and the
full toolbox is here. If you do run it: R installed, nMonte3.R plus a
data and target file in the working directory, source('nMonte3.R'), and the sheet
discipline above observed with the seriousness the script itself will never demand.
A ten-year-old R script with no test, no errors bars and no opinions became the load-bearing tool of an entire hobby — which is exactly why knowing its shape matters. The percentages were never the script's claim. They were always yours.
Terms used here are defined in the glossary.



