aosabook/500lines · error · ValueError
event probabilities do not sum to 1
Error message
event probabilities do not sum to 1
What it means
Raised by the constructor of the multinomial distribution class in the sampler chapter. It validates that the supplied event-probability vector p sums to 1 using np.isclose(np.sum(p), 1.0) to tolerate floating-point drift; if not close it raises ValueError('event probabilities do not sum to 1'). The probabilities are then stored and used to precompute log-probabilities for the log-PMF.
Source
Thrown at sampler/sampler.markdown:223
def __init__(self, p, rso=np.random):
"""Initialize the multinomial random variable.
Parameters
----------
p: numpy array of length `k`
The event probabilities
rso: numpy RandomState object (default: None)
The random number generator
"""
# Check that the probabilities sum to 1. If they don't, then
# something is wrong! We use `np.isclose` rather than checking
# for exact equality because in many cases, we won't have
# exact equality due to floating-point error.
if not np.isclose(np.sum(p), 1.0):
raise ValueError("event probabilities do not sum to 1")
# Store the parameters that were passed in
self.p = p
self.rso = rso
# Precompute log probabilities, for use by the log-PMF, for
# each element of `self.p` (the function `np.log` operates
# elementwise over NumPy arrays, as well as on scalars.)
self.logp = np.log(self.p)
```
The class takes as arguments the event probabilities, $p$, and a
variable called `rso`. First, the constructor checks that the
parameters are valid; i.e., that `p` sums to 1. Then it stores
the arguments that were passed in, and uses the event probabilities to
compute the event *log* probabilities. (We'll go into why this is
necessary in a bit). The `rso` object is what we'll use later to
produce random numbers. (We'll talk more about what it is a bit laterView on GitHub (pinned to fba689d101)
Solutions
- Normalise the vector before constructing: p = np.asarray(p, float); p = p / p.sum().
- Fix the source data so the intended probabilities genuinely sum to 1.
- If the values are weights, divide by their sum explicitly and document the transformation.
- Verify the array is non-empty and 1-D of length k.
Example fix
# before p = np.array([0.2, 0.3, 0.3]) # sum 0.8 -> ValueError dist = MultinomialDistribution(p, rso) # after: normalise first p = np.array([0.2, 0.3, 0.3], dtype=float) p = p / p.sum() # -> [0.25, 0.375, 0.375], sum 1.0 assert np.isclose(p.sum(), 1.0) dist = MultinomialDistribution(p, rso)
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
p = np.asarray(raw_p, dtype=float)
assert p.ndim == 1 and p.size > 0, 'p must be a non-empty 1-D array'
if not np.isclose(p.sum(), 1.0):
p = p / p.sum() # normalise in place
assert np.isclose(p.sum(), 1.0)
dist = MultinomialDistribution(p, rso=rso) Type guard
def is_probability_vector(p):
p = np.asarray(p, dtype=float)
return p.ndim == 1 and p.size > 0 and np.all(p >= 0) and np.isclose(p.sum(), 1.0) Try / catch
try:
dist = MultinomialDistribution(p, rso=rso)
except ValueError as e:
if 'sum to 1' in str(e):
p = np.asarray(p, float) / np.sum(p)
dist = MultinomialDistribution(p, rso=rso)
else:
raise Prevention
- Normalise at the data-loading boundary, not at every construction.
- Reject negative entries alongside the sum check.
- Pin numpy version so np.isclose tolerance is stable across envs.
- Add a unit test that feeds [0.2,0.3,0.3] and expects success after normalisation.
When it happens
Trigger: Constructing the distribution with a p whose sum is not ~1.0, e.g. [0.3, 0.3] (sum 0.6), [0.5, 0.6] (sum 1.1), or an empty array. Fires at instantiation time, before any sampling.
Common situations: Reading probabilities from a config/CSV that were not normalised; hand-tuning weights and forgetting to renormalise; rounding/truncation that drifts the sum outside np.isclose tolerance (~1e-8 relative); passing log-probabilities or counts instead of probabilities.
AI-assisted analysis of aosabook/500lines@fba689d101 (2026-08-13).
Data as JSON: /api/errors/05ec572dbc3d7ab2.
Report an issue: GitHub.