IV.9 · Probability
How many different sequences produce the same success count?
Begin with one binary trial, then group independent trial sequences by their total successes. The binomial coefficient counts the ways to place those successes.
Count successes in independent trials
Success count k · colored selected bars carry probability mass
Filled dot gives F(k); an open dot marks the left limit at a positive jump. F ends at one.
Binomial n=8, p=35 percent. Selected k=3, exact mass 0.2785857790625. Selected closed interval [0, 8]. PMF bars carry exact point masses. The closed interval has mass 1. A CDF includes the jump at its argument: subtract F(ℓ−), not F(ℓ), for a closed interval.
- Selected binomial mass
- 0.2785857790625
- Total finite mass
- 1
- Expectation
- 2.8
- Variance
- 1.82
= exact model quantity · ≈ numerical companion or observed estimate
from 0 to 30, whole numbers only
from 0 to 100, up to 2 decimal places
from −1 to 31, whole numbers only
Start with individual trial outcomes
8 iid Bernoulli trials, p=0.35. Empty products are one in this counting context; n=0 means zero successes with probability one.
Predict the three masses before reading them. Set the selected count outside the support and distinguish an impossible event from an invalid experiment.
Intuition: binary trials, numerical totals
A trial records success as and failure as . “Success” is simply the event being counted; it need not mean a desirable result. One trial is a Bernoulli variable. Adding several trials produces a success count.
For two fair independent trials, the sequences are . Their counts are . The same grouping principle from random variables yields three count values, with more mass in the middle because two sequences feed it.
Definition
A Bernoulli variable with parameter has and . If are independent Bernoulli variables with the same , then
Outside that integer support, the mass is zero. The parameter is a nonnegative integer; is valid. For , the binomial model is Bernoulli. Independence and a common success probability are assumptions, not consequences of using binary labels.
Mechanics: parameters and selected events
The stage accepts integer from through , success percentage from through with two decimal places, and selected integer from through . These are teaching controls; divide a percentage by to obtain the probability parameter. The selected identifies one event without changing the distribution.
Follow the trace from selecting success positions, through the probability of one such sequence, to their product. Compare the selected PMF mass with its CDF jump. Selecting or yields mass zero; it must not be silently clamped to a possible count. Invalid parameters, such as negative or , instead fail to define this model.
Derivation: multiply first, then count
Independence makes any particular length- sequence with successes have mass . A common makes this mass the same for every sequence with that count. There are choices of success positions, giving the PMF above.
The binomial theorem checks its total:
With zero trials, the one empty sequence has success count and mass . A zero exponent here denotes an empty product of value , including boundary factors written in this combinatorial formula. This convention concerns empty products; it is not a universal statement about indeterminate limits.
Worked examples
For , , all four sequences have mass . Grouping gives , , . A single count label does not mean a single source sequence.
Worked example: Count successes in independent trials
Success count k · colored selected bars carry probability mass
Filled dot gives F(k); an open dot marks the left limit at a positive jump. F ends at one.
Binomial n=8, p=35 percent. Selected k=3, exact mass 0.2785857790625. Selected closed interval [0, 8]. PMF bars carry exact point masses. The closed interval has mass 1. A CDF includes the jump at its argument: subtract F(ℓ−), not F(ℓ), for a closed interval.
- Selected binomial mass
- 0.2785857790625
- Total finite mass
- 1
- Expectation
- 2.8
- Variance
- 1.82
= exact model quantity · ≈ numerical companion or observed estimate
from 0 to 30, whole numbers only
from 0 to 100, up to 2 decimal places
from −1 to 31, whole numbers only
Start with individual trial outcomes
8 iid Bernoulli trials, p=0.35. Empty products are one in this counting context; n=0 means zero successes with probability one.
For , , exactly one success can occupy three positions. Each corresponding sequence has mass , so
At , all mass lies at . At , all mass lies at . For , these both name the same count. No factorial of a negative integer is needed for an impossible selected event.
Executable reference code
The exact program uses standard-library comb and Fraction, returning zero before evaluating an out-of-support count. It checks literal worked values and sweeps across deterministic, near-boundary, and ordinary probabilities, asserting normalization and mean . Fraction('12.34') / 100 represents exactly.
The NumPy program exposes the coefficient array and elementwise powers. It compares each mass against exact rational products within absolute tolerance , with no SciPy dependency and no random sampling.
"""Exact binomial masses; no factorial at an impossible count.
The stage accepts n in 0..30, selected k in -1..31, and p-percent to two
decimal places. Fraction('12.34') / 100 represents 12.34% exactly.
"""
from fractions import Fraction as F
from math import comb
def pmf(n, p, k):
if type(n) is not int or not 0 <= n <= 30 or type(k) is not int or not -1 <= k <= 31:
raise ValueError("Require integer n in 0..30 and integer k in -1..31")
if not isinstance(p, F) or not 0 <= p <= 1:
raise ValueError("Success probability must be a Fraction in [0, 1]")
if k < 0 or k > n:
return F(0)
# An exponent of zero denotes the empty product, including at p = 0 or 1.
return comb(n, k) * p**k * (1 - p)**(n - k)
def main():
assert [pmf(2, F(1, 2), k) for k in range(3)] == [F(1, 4), F(1, 2), F(1, 4)]
assert pmf(3, F(1, 4), 1) == F(27, 64)
assert pmf(0, F(2, 5), 0) == 1
assert pmf(0, F(2, 5), 1) == 0
assert pmf(3, F(0), 0) == pmf(3, F(1), 3) == 1
assert pmf(2, F(1, 2), -1) == pmf(2, F(1, 2), 3) == 0
percentage = F('12.34') / 100
assert percentage == F(617, 5000)
for n in range(31):
for p in (F(0), F(1, 10000), percentage, F(1, 2), F(9999, 10000), F(1)):
distribution = [pmf(n, p, k) for k in range(n + 1)]
assert sum(distribution, F(0)) == 1
assert sum((k * mass for k, mass in enumerate(distribution)), F(0)) == n * p
for args in ((-1, F(1, 2), 0), (31, F(1, 2), 0), (2, F(-1), 0), (2, F(2), 0), (2, 0.5, 1), (2, F(1, 2), 1.5)):
try:
pmf(*args)
except ValueError:
pass
else:
raise AssertionError("Invalid binomial parameters accepted")
print("Binomial(2, 1/2) exact:", [pmf(2, F(1, 2), k) for k in range(3)])
print("Binomial(3, 1/4), k = 1:", pmf(3, F(1, 4), 1))
print("Zero trials:", pmf(0, percentage, 0), "; impossible k:", pmf(2, percentage, 3))
if __name__ == "__main__":
main()"""Vectorize binomial products without adding SciPy; comb stays exact."""
from fractions import Fraction as F
from math import comb
import numpy as np
def distribution(n, p):
if type(n) is not int or not 0 <= n <= 30 or not np.isfinite(p) or not 0 <= p <= 1:
raise ValueError("Require integer n in 0..30 and finite p in [0, 1]")
k = np.arange(n + 1)
coefficients = np.array([comb(n, int(j)) for j in k], dtype=float)
# NumPy's exponent-zero result is 1, implementing the empty product.
return coefficients * np.power(p, k) * np.power(1 - p, n - k)
def selected_mass(n, p, k):
masses = distribution(n, p)
if type(k) is not int or not -1 <= k <= 31:
raise ValueError("Require integer k in -1..31")
return 0.0 if k < 0 or k > n else float(masses[k])
def main():
np.testing.assert_array_equal(distribution(2, 0.5), [0.25, 0.5, 0.25])
assert selected_mass(3, 0.25, 1) == 27/64
assert selected_mass(0, 0.4, 0) == 1
assert selected_mass(0, 0.4, 1) == 0
assert selected_mass(3, 0, 0) == selected_mass(3, 1, 3) == 1
assert selected_mass(2, 0.5, -1) == selected_mass(2, 0.5, 3) == 0
for n in range(31):
for p_exact in (F(0), F(1, 10000), F(617, 5000), F(1, 2), F(9999, 10000), F(1)):
masses = distribution(n, float(p_exact))
exact = [comb(n, k) * p_exact**k * (1 - p_exact)**(n - k) for k in range(n + 1)]
np.testing.assert_allclose(masses, [float(x) for x in exact], rtol=0, atol=1e-12)
np.testing.assert_allclose(masses.sum(), 1, rtol=0, atol=1e-12)
np.testing.assert_allclose(np.dot(np.arange(n + 1), masses), float(n * p_exact), rtol=0, atol=1e-12)
for n, p, k in ((-1, .5, 0), (31, .5, 0), (2, np.nan, 0), (2, np.inf, 0), (2, 1.1, 0), (2, .5, 1.5)):
try:
selected_mass(n, p, k)
except ValueError:
pass
else:
raise AssertionError("Invalid binomial parameters accepted")
print("Binomial(2, 1/2) ≈", distribution(2, .5))
print("n = 30, p = 12.34%, k = 4 ≈", selected_mass(30, .1234, 4))
if __name__ == "__main__":
main()Explore
Hold while moving from to . Predict where mass collects at either end. Set and increase : the support grows, but the selected event still asks for one count. Try with both and . Reset returns the stage’s starting model , , .
For , , select and explain the factor in the trace. Compare with and reflect the count into : the success/failure roles swap, giving the same mass under the reflected parameter.
Common mistakes and counterexamples
Three possible counts for two trials are not equally likely. Counting labels would yield three masses and discard sequence multiplicity. Also, is a probability, not the percentage number: means , not .
Equal trial marginals alone are insufficient. If the second trial always copies the first fair trial, the count is or , each with mass , and never . Independent trials with differing success probabilities also need a different count model; one common cannot encode them.
Numerical considerations
Finite decimal percentages can be represented as exact rational inputs. Exact references avoid rounded factorial ratios by using integer combinations. The stage’s bounded keeps its examples small, but floating-point masses remain approximations unless an exact form is supplied.
Boundary values deserve deliberate checks: , , , and impossible are valid cases with exact answers. Do not use a numerical epsilon to declare a small positive probability zero. General large- algorithms would require additional numerical care beyond this bounded lesson.
Engineering and ML connections
Binary indicators count errors, accepted requests, or successful tests. A binomial model is appropriate when independence and constant success probability are justified by the experiment. Reused inputs, common failures, or changing difficulty can violate those assumptions; a convenient formula does not repair the model.
Exercises
Enter exact fractions for the finite probabilities. Check boundaries using their experiment meaning as well as the formula.
Summary and checkpoints
A Bernoulli variable records one binary event; a binomial variable counts independent trials with common . Check that you can explain both sequence probability and multiplicity, compute for the worked three-trial event, and handle zero trials, deterministic parameters, and impossible selected counts without changing the question.