Here is a solution to the generalised problem using other modulo
The other answers here are wonderful, but I can't help but scratch the itch to generalise your problem. Consider the generalised problem where we have a sequence $X_1,X_2,X_3,...$ with independent binary values having $X_i \sim \text{Bern}(p_i)$. Now define the modular-remainders of the sums of interest as:
$$M_{n,k} \equiv\bigg( \sum_{i=1}^n X_i \bigg) \text{ mod } k$$
for $n=1,2,3,...$ and $k=2,3,4,...$. We want to compute the probability distribution for this statistic, with probabilities denoted by:
$$\psi_{n,k}(m) \equiv \mathbb{P}(M_{n,k} = m)
\quad \quad \quad \quad \quad
\text{for } m =0,...,k-1.$$
Your question is seeking the probability $\psi_{n,2}(0)$, which occurs in the case $k=2$ where the value $M_{n,2}$ is an indicator that the sum of the first $n$ values in the sequence is even.
Recursive computation of the probability of interest: In this general case we can use an extension of the recursive algorithm given in the wonderful answer by Stephen Kolassa. To do this, we can use the base equation:
$$\psi_{0,k}(m) = \mathbb{I}(m=0).$$
and the recursive equation:
$$\psi_{n+1,k}(m)
= (1-p_{n+1}) \cdot \psi_{n,k}(m) + p_{n+1} \cdot \psi_{n,k} ((m-1) \text{ mod } k).$$
You can find a similar generalisation relating to an associated problem in this related answer. It is possible to obtain a closed-form solution for the probability function of interest (as opposed to a recursive formula) using the method described in the linked question. Here we will proceed using the recursive computation, which allows efficient computation of matrices of probabilities in cases where we are interested in all sample sizes up to some upper bound.
Implementation: We can implement this recursive method in R
using a function that takes n
, k
and p
as inputs and generating the vector of probabilities over all relevant values of $m$. (Note: In the function below, for the input p
we can take this as either a vector of probabilities that is at least $n$ elements long, or a function that generates a probability for any positive integer input to allow a full sequence of probabilities.) The function defaults to the binary case that is of interest to you but it allows different values of k
to be set by the user.
modular.prob <- function(n, p, k=2, keep.all = FALSE) {
#Check inputs n and k
if (!is.numeric(n)) stop('Error: Input n should be a number')
if (!is.numeric(k)) stop('Error: Input k should be a number')
if (length(n) != 1) stop('Error: Input n should be a single number')
if (length(k) != 1) stop('Error: Input k should be a single number')
if (n != as.integer(n)) stop('Error: Input n should be an integer')
if (k != as.integer(k)) stop('Error: Input k should be an integer')
if (min(n < 0)) stop('Error: Input n should be a non-negative integer')
if (min(k < 1)) stop('Error: Input n should be a positive integer')
#Check input p
if (is.function(p)) {
if (length(formals(p)) != 1) {
stop('Error: If input p is a function, it should only have a single argument') }
pp <- rep(0, n)
for (i in 1:n) { pp[i] <- p(i) }
} else {
if (!is.numeric(p)) stop('Error: Input p should be a numeric vector')
if (length(p) < n) stop('Error: Input p should have at least n elements')
pp <- p[1:n]
if (min(pp) < 0) stop('Error: Input p should have values between zero and one')
if (max(pp) > 1) stop('Error: Input p should have values between zero and one') }
#Check input keep.all
if (!is.logical(keep.all)) stop('Error: Input keep.all should be a logical value')
if (length(keep.all) != 1) stop('Error: Input keep.all should be a single logical value')
#Set probability matrix
PROBS <- matrix(0, nrow = n+1, ncol = k)
rownames(PROBS) <- sprintf('n[%s]', 0:n)
colnames(PROBS) <- sprintf('m[%s]', 1:k-1)
if (k == 2) { colnames(PROBS) <- c('Even', 'Odd') }
#Compute probabilities
#Trivial case where k = 1 is treated without recursion
PROBS[1, 1] <- 1
if (k == 1) { PROBS[, 1] <- 1 }
if (k > 1) {
for (i in 1:n) {
PP <- PROBS[i, ]
PROBS[i+1, ] <- (1-pp[i])*PP + pp[i]*PP[c(k, 1:(k-1))] } }
#Give output
if (keep.all) { PROBS } else { PROBS[n+1, ] } }
Here is an example implementing the function with a specified probability vector with $n=20$ elements. We first compute the probabilities for even/odd sums using $k=2$ and we then compute the probabilities for modular remainders with $k=3$. In each case we get a matrix of probabilities for each trial and each modular remainder.
#Set probability vector (with twenty elements)
p <- c(0.1, 0.2, 0.3, 0.2, 0.1, 0.6, 0.2, 0.2, 0.5, 0.1,
0.9, 0.2, 0.2, 0.1, 0.4, 0.5, 0.6, 0.4, 0.2, 0.8)
#Compute probabilities of even/odd sums
modular.prob(n = 20, p = p, keep.all = TRUE)
Even Odd
n[0] 1.0000000 0.0000000
n[1] 0.9000000 0.1000000
n[2] 0.7400000 0.2600000
n[3] 0.5960000 0.4040000
n[4] 0.5576000 0.4424000
n[5] 0.5460800 0.4539200
n[6] 0.4907840 0.5092160
n[7] 0.4944704 0.5055296
n[8] 0.4966822 0.5033178
n[9] 0.5000000 0.5000000
n[10] 0.5000000 0.5000000
n[11] 0.5000000 0.5000000
n[12] 0.5000000 0.5000000
n[13] 0.5000000 0.5000000
n[14] 0.5000000 0.5000000
n[15] 0.5000000 0.5000000
n[16] 0.5000000 0.5000000
n[17] 0.5000000 0.5000000
n[18] 0.5000000 0.5000000
n[19] 0.5000000 0.5000000
n[20] 0.5000000 0.5000000
#Compute probabilities for ternary modular remainders
modular.prob(n = 20, p = p, k = 3, keep.all = TRUE)
m[0] m[1] m[2]
n[0] 1.0000000 0.0000000 0.0000000
n[1] 0.9000000 0.1000000 0.0000000
n[2] 0.7200000 0.2600000 0.0200000
n[3] 0.5100000 0.3980000 0.0920000
n[4] 0.4264000 0.4204000 0.1532000
n[5] 0.3990800 0.4210000 0.1799200
n[6] 0.2675840 0.4078480 0.3245680
n[7] 0.2789808 0.3797952 0.3412240
n[8] 0.2914294 0.3596323 0.3489382
n[9] 0.3201838 0.3255309 0.3542853
n[10] 0.3235940 0.3249962 0.3514098
n[11] 0.3486283 0.3237342 0.3276375
n[12] 0.3444301 0.3287130 0.3268569
n[13] 0.3409155 0.3318564 0.3272281
n[14] 0.3395467 0.3327623 0.3276909
n[15] 0.3348044 0.3354761 0.3297195
n[16] 0.3322620 0.3351403 0.3325978
n[17] 0.3324635 0.3334133 0.3341233
n[18] 0.3331274 0.3330333 0.3338393
n[19] 0.3332698 0.3330522 0.3336781
n[20] 0.3335964 0.3332262 0.3331773
As exhibited in the outputs above, typically we will see that $M_{n,k}$ converges in distribution to the uniform distribution as $n \rightarrow \infty$. This can be proved formally using the CLT - it occurs due to the fact that the standardised sum of the binary values converges in distribution to a continuous distribution (the normal distribution) and so the modular-remainder over shorter and shorter intervals converges to uniform probabilities.