codexmajority-parity-query-cost-distributions.py
majority-parity-query-cost-distributions.py
"""Enumerate uniform three-bit query costs. Python 3.14, matplotlib 3.10.7.
Run from _media; the opaque PNG is written to the current directory.
"""
from itertools import product
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def main():
inputs = list(product((0, 1), repeat=3))
majority_reads = [(0, 1) if x[0] == x[1] else (0, 1, 2) for x in inputs]
parity_reads = [(0, 1, 2) for _ in inputs]
costs = [[len(reads) for reads in algorithm] for algorithm in (majority_reads, parity_reads)]
revealments = [[sum(i in reads for reads in algorithm) / len(inputs) for i in range(3)]
for algorithm in (majority_reads, parity_reads)]
assert costs[0] == [2, 2, 3, 3, 3, 3, 2, 2]
assert revealments == [[1.0, 1.0, 0.5], [1.0, 1.0, 1.0]]
plt.rcParams.update({"font.size": 12, "font.family": "DejaVu Sans"})
fig, axes = plt.subplots(1, 2, figsize=(9, 4.9), facecolor="white")
colors = ["#2563eb", "#c2410c"]
names = ["Majority: stop on agreement", "Parity: read all three"]
width = 0.32
for j, (values, label, color) in enumerate(zip(costs, names, colors)):
probabilities = [values.count(q) / len(inputs) for q in (2, 3)]
bars = axes[0].bar(np.array([2, 3]) + (j - 0.5) * width, probabilities, width,
color=color, label=label)
axes[0].bar_label(bars, labels=[f"{p:g}" for p in probabilities], padding=4)
bars = axes[1].bar(np.arange(1, 4) + (j - 0.5) * width, revealments[j], width,
color=color)
axes[1].bar_label(bars, labels=[f"{p:g}" for p in revealments[j]], padding=4)
axes[0].set(title="Query-count distribution", xlabel="Number of queries q",
ylabel="Probability", xticks=[2, 3])
axes[1].set(title="Coordinate revealment", xlabel="Coordinate inspected",
xticks=[1, 2, 3], xticklabels=[r"$x_1$", r"$x_2$", r"$x_3$"])
for ax in axes:
ax.set_ylim(0, 1.17)
ax.set_yticks([0, 0.5, 1])
ax.spines[["top", "right"]].set_visible(False)
ax.set_axisbelow(True)
ax.grid(axis="y", alpha=0.2)
fig.suptitle("Uniform inputs: same worst-case depth, different query costs", fontsize=16)
fig.legend(*axes[0].get_legend_handles_labels(), loc="lower center", ncol=2,
frameon=False, bbox_to_anchor=(0.5, 0.115), fontsize=11)
fig.text(0.5, 0.045, "Majority: E[q] = 2.5 = 1 + 1 + 0.5 | Parity: E[q] = 3 = 1 + 1 + 1",
ha="center", fontsize=12)
fig.subplots_adjust(left=0.09, right=0.98, bottom=0.29, top=0.79, wspace=0.30)
fig.savefig(Path(__file__).with_suffix(".png").name, dpi=120,
facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()