codexnegative-covariance-fixed-size-sampling.py
negative-covariance-fixed-size-sampling.py
"""Enumerate a uniform two-of-four sample and its inclusion indicators."""
from itertools import combinations
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def main():
samples = list(combinations(range(1, 5), 2))
values = np.array([[int(1 in s), int(2 in s)] for s in samples])
assert np.allclose(np.cov(values.T, bias=True), [[.25, -1/12], [-1/12, .25]])
counts = np.zeros((2, 2), dtype=int)
for i, j in values:
counts[i, j] += 1
assert counts.tolist() == [[1, 2], [2, 1]]
fig, (ax, note) = plt.subplots(1, 2, figsize=(7.2, 3.6), dpi=100,
layout="constrained", width_ratios=[1, 1])
fig.set_facecolor("white")
ax.imshow(counts/6, vmin=0, vmax=.5, cmap="Blues", origin="lower")
for i in range(2):
for j in range(2):
ax.text(j, i, "1/6" if counts[i, j] == 1 else "1/3",
ha="center", va="center", fontsize=18)
ax.set(xticks=[0, 1], yticks=[0, 1], xlabel="Indicator I₂", ylabel="Indicator I₁",
title="Joint probabilities")
note.axis("off")
note.text(.05, .95, "Six equally likely samples\n\n" +
"\n".join(f"{{{s[0]}, {s[1]}}} → ({v[0]}, {v[1]})"
for s, v in zip(samples, values)) +
"\n\nCovariance = −1/12\nCorrelation = −1/3",
transform=note.transAxes, va="top", fontsize=11, linespacing=1.35)
fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()