Algorithm Search⌘K

Proofs: Fischer-Paterson algorithm

These are the human proofs of Fischer-Paterson algorithm, at full length.

The Fischer-Paterson method computes all Hamming distances full

This proof shows: correctness.

Indices are 0-based, 1≤m≤n1 \le m \le n, and h[i]=∣{r∈{0,…,m−1}:P[r]≠T[i+r]}∣h[i] = |\{ r \in \{0, \ldots, m-1\} : P[r] \ne T[i + r] \}| for 0≤i≤n−m0 \le i \le n - m. Let SS be the set of distinct symbols of PP. For c∈Sc \in S, xc[q]=[P[m−1−q]=c]x_c[q] = [P[m-1-q] = c] for 0≤q<m0 \le q < m, and for a block start bb, yc,b[j]=[T[b+j]=c]y_{c,b}[j] = [T[b + j] = c] for 0≤j<ℓb0 \le j < \ell_b, where ℓb=min⁡(2m−1,n−b)\ell_b = \min(2m - 1, n - b). All other entries of the vectors of length NN are 0, and N≥3m−2N \ge 3m - 2.

Lemma 1 (one block, one symbol). Let z=xc∗yc,bz = x_c * y_{c,b} be the linear convolution, z[s]=∑q+j=sxc[q] yc,b[j]z[s] = \sum_{q + j = s} x_c[q]\, y_{c,b}[j]. For each tt with 0≤t≤m−10 \le t \le m - 1 and b+t≤n−mb + t \le n - m,

z[t+m−1]=∣{r∈{0,…,m−1}:P[r]=c and T[b+t+r]=c}∣.z[t + m - 1] = |\{ r \in \{0, \ldots, m-1\} : P[r] = c \text{ and } T[b + t + r] = c \}|.

Proof. z[t+m−1]=∑q=0m−1xc[q] yc,b[t+m−1−q]z[t + m - 1] = \sum_{q=0}^{m-1} x_c[q]\, y_{c,b}[t + m - 1 - q], since xc[q]=0x_c[q] = 0 for q≥mq \ge m and the index j=t+m−1−qj = t + m - 1 - q is at least t≥0t \ge 0. Substitute r=m−1−qr = m - 1 - q, which runs over 0,…,m−10, \ldots, m - 1: the term is [P[r]=c]⋅yc,b[t+r][P[r] = c] \cdot y_{c,b}[t + r]. Here t+r≤2m−2<2m−1t + r \le 2m - 2 < 2m - 1 and b+t+r≤(n−m)+(m−1)=n−1b + t + r \le (n - m) + (m - 1) = n - 1, so t+r<ℓbt + r < \ell_b and yc,b[t+r]=[T[b+t+r]=c]y_{c,b}[t + r] = [T[b + t + r] = c]. The sum of the products of the two indicators counts the stated set. □\square

Lemma 2 (the transform is exact). Line L6 returns zz exactly.

Proof. xcx_c has nonzero entries only below mm and yc,by_{c,b} only below 2m−12m - 1, so z[s]=0z[s] = 0 for s>3m−3s > 3m - 3, and the linear convolution has length at most 3m−2≤N3m - 2 \le N. The pointwise product of the transforms of length NN gives the cyclic convolution z~[s]=∑q+j≡s(modN)xc[q] yc,b[j]\tilde z[s] = \sum_{q + j \equiv s \pmod N} x_c[q]\, y_{c,b}[j]. A pair with q+j≥Nq + j \ge N would need q+j≥3m−2q + j \ge 3m - 2, but q+j≤(m−1)+(2m−2)=3m−3q + j \le (m - 1) + (2m - 2) = 3m - 3. So z~=z\tilde z = z. Over the integers modulo the prime p=998244353p = 998244353, the number-theoretic transform satisfies the same convolution theorem, because NN is a power of two that divides p−1p - 1, so a primitive NN-th root of unity exists. So the result is z[s] mod pz[s] \bmod p. Each z[s]z[s] is a count of at most mm pairs, and 0≤z[s]≤m<p0 \le z[s] \le m < p, so z[s] mod p=z[s]z[s] \bmod p = z[s]. □\square

Lemma 3 (the blocks). Each i∈{0,…,n−m}i \in \{0, \ldots, n - m\} receives a contribution in line L7 from exactly one block per symbol, the one with b=m⌊i/m⌋b = m \lfloor i / m \rfloor, at t=i−bt = i - b.

Proof. The blocks have b=0,m,2m,…b = 0, m, 2m, \ldots with b≤n−mb \le n - m. Line L7 of block bb adds to A[b+t]A[b + t] for 0≤t≤min⁡(m,n−m+1−b)−10 \le t \le \min(m, n - m + 1 - b) - 1, that is, for the starts b,…,min⁡(b+m−1,n−m)b, \ldots, \min(b + m - 1, n - m). These ranges are disjoint for different bb, since each has length at most mm and they start mm apart, and their union is {0,…,n−m}\{0, \ldots, n - m\}, since the last block has b>n−2mb > n - 2m and its range ends at n−mn - m. The block that contains ii is the one with b≤i<b+mb \le i < b + m, that is, b=m⌊i/m⌋b = m \lfloor i/m \rfloor, and this b≤i≤n−mb \le i \le n - m is one of the blocks of line L4. □\square

Theorem. FP-HAMMING returns hh.

Proof. By Lemmas 1 to 3, after the loops,

A[i]=∑c∈S∣{r:P[r]=c and T[i+r]=c}∣.A[i] = \sum_{c \in S} |\{ r : P[r] = c \text{ and } T[i + r] = c \}|.

For each rr, the condition P[r]=c=T[i+r]P[r] = c = T[i + r] holds for at most one cc, namely c=P[r]∈Sc = P[r] \in S, and it holds for that cc exactly when P[r]=T[i+r]P[r] = T[i + r]. So the sets in the sum are disjoint, and their union is {r:P[r]=T[i+r]}\{ r : P[r] = T[i + r] \}. So A[i]=m−h[i]A[i] = m - h[i], and line L8 returns h[i]=m−A[i]h[i] = m - A[i]. ■\blacksquare

Back to Fischer-Paterson algorithm