codextail-events-independent-and-shared-coin-probabilities.py
tail-events-independent-and-shared-coin-probabilities.py
"""Compare exact probabilities, not simulated frequencies (Python 3.14)."""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def main():
r = np.arange(1, 13)
independent = 1 - np.exp2(-r.astype(float))
shared = np.full(r.shape, 0.5)
fig, ax = plt.subplots(figsize=(9, 5.6), dpi=120, facecolor='white')
ax.set_facecolor('white')
fig.suptitle('At least one head in a window of r coordinates', fontsize=17, weight='bold', y=0.96)
ax.plot(r, independent, 'o-', color='#1766a3', lw=2.4,
label=r'Independent fair coins: $1-2^{-r}$', markersize=5)
ax.plot(r, shared, 's-', color='#d16a13', lw=2.4,
label=r'One shared fair coin: $1/2$', markersize=5)
ax.axhline(1, color='#7c858f', ls='--', lw=1.2)
ax.text(12.1, 1, '1', va='center', color='#555d66')
ax.annotate('r = 3: 7/8', xy=(3, 0.875), xytext=(4.1, 0.75),
arrowprops={'arrowstyle': '->', 'color': '#1766a3'}, fontsize=12, color='#1766a3')
ax.text(6.4, 0.55, r'$X_j=Z$ for every $j$: no new chance', fontsize=12, color='#b45810')
ax.set(xlim=(0.7, 12.6), ylim=(0, 1.06), xlabel='Window length r', ylabel='Exact model probability')
ax.set_xticks([1, 2, 3, 4, 6, 8, 10, 12])
ax.set_yticks([0, 0.25, 0.5, 0.75, 1])
ax.grid(alpha=0.2)
ax.spines[['top', 'right']].set_visible(False)
ax.legend(loc='lower right', framealpha=1, facecolor='white', fontsize=11)
fig.text(0.5, 0.035, 'Constructed probability curves • no measurements or simulation',
ha='center', fontsize=11, color='#4c5662')
fig.subplots_adjust(left=0.09, right=0.96, bottom=0.16, top=0.86)
fig.savefig(Path.cwd() / f'{Path(__file__).stem}.png', facecolor='white')
plt.close(fig)
if __name__ == '__main__':
main()