codex/interval-dependency-and-subdivision.py

interval-dependency-and-subdivision.py
"""Dependency, exact subdivision enclosures and a square-range comparison.

Save interval-dependency-and-subdivision.png to the current working directory.
Bounds and verification use Fraction; floats are used only for drawing.
Tested with Python 3.14.4, Matplotlib 3.10.7 and NumPy 2.3.5.
"""

from fractions import Fraction as Q
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np


def subtract(x, y):
    return x[0] - y[1], x[1] - y[0]


def multiply(x, y):
    products = [u * v for u in x for v in y]
    return min(products), max(products)


def square_range(x):
    squares = [u * u for u in x]
    return (Q(0) if x[0] <= 0 <= x[1] else min(squares), max(squares))


def enclosure(x):
    return multiply(x, subtract((Q(1), Q(1)), x))


def pieces(n):
    return [(Q(j, n), Q(j + 1, n)) for j in range(n)]


def verify():
    unit = (Q(0), Q(1))
    assert subtract(unit, unit) == (Q(-1), Q(1))
    expected = {
        1: [(Q(0), Q(1))],
        2: [(Q(0), Q(1, 2))] * 2,
        4: [(Q(0), Q(1, 4)), (Q(1, 8), Q(3, 8)),
            (Q(1, 8), Q(3, 8)), (Q(0), Q(1, 4))],
    }
    for n, bounds in expected.items():
        assert [enclosure(x) for x in pieces(n)] == bounds
        for x in pieces(n):
            low, high = enclosure(x)
            for j in range(101):
                t = x[0] + (x[1] - x[0]) * Q(j, 100)
                assert low <= t * (1 - t) <= high
    z = subtract(unit, (Q(1, 2), Q(1, 2)))
    assert square_range(z) == (Q(0), Q(1, 4))
    assert multiply(z, z) == (Q(-1, 4), Q(1, 4))
    assert subtract((Q(1, 4), Q(1, 4)), square_range(z)) == (Q(0), Q(1, 4))
    assert subtract((Q(1, 4), Q(1, 4)), multiply(z, z)) == (Q(0), Q(1, 2))


def main():
    verify()
    plt.rcParams.update({"font.size": 11, "axes.titlesize": 12})
    fig = plt.figure(figsize=(10, 7), dpi=100, facecolor="white")
    grid = fig.add_gridspec(2, 2, height_ratios=(1.25, 1), hspace=0.53, wspace=0.37)
    cartesian = fig.add_subplot(grid[0, 0])
    local = fig.add_subplot(grid[0, 1])
    bars = fig.add_subplot(grid[1, :])
    fig.suptitle("Interval dependency: one input, two independent copies", fontsize=16, y=0.97)

    # The color field is illustrative; all interval bounds are exact Fractions.
    u, v = np.meshgrid(np.linspace(0, 1, 151), np.linspace(0, 1, 151))
    cartesian.pcolormesh(u, v, u * (1 - v), shading="auto", cmap="Blues", vmin=0, vmax=1)
    cartesian.plot([0, 1], [0, 1], color="#bb3e28", lw=3)
    cartesian.scatter([1], [0], color="#bb3e28", zorder=4)
    cartesian.annotate("u = 1, v = 0\noutput = 1", (1, 0), (0.57, 0.14),
                       arrowprops={"arrowstyle": "->", "color": "#bb3e28"}, fontsize=10)
    cartesian.text(0.06, 0.72, "Actual inputs:\nu = v only", color="#9b291c",
                   bbox={"facecolor": "white", "edgecolor": "none", "alpha": 0.9})
    cartesian.set(title="Independent evaluation: u(1 − v)", xlabel="First copy u", ylabel="Second copy v",
                  xlim=(0, 1), ylim=(0, 1), xticks=(0, 0.5, 1), yticks=(0, 0.5, 1))

    for x in pieces(4):
        low, high = enclosure(x)
        local.add_patch(Rectangle((float(x[0]), float(low)), float(x[1] - x[0]),
                                  float(high - low), facecolor="#dbe9f4", edgecolor="#3479a7", lw=1.5))
    samples = [Q(j, 400) for j in range(401)]
    local.plot([float(x) for x in samples], [float(x * (1 - x)) for x in samples],
               color="#bb3e28", lw=2.5, label="Actual f(x) = x(1 − x)")
    local.axhline(float(Q(1, 4)), color="#bb3e28", ls=":", lw=1)
    local.set(title="Four pieces: local enclosing rectangles", xlabel="Same input x in both factors",
              ylabel="Output", xlim=(0, 1), ylim=(0, 0.42), xticks=(0, 0.25, 0.5, 0.75, 1),
              yticks=(0, 0.125, 0.25, 0.375), yticklabels=("0", "1/8", "1/4", "3/8"))
    local.legend(loc="upper center", bbox_to_anchor=(0.5, -0.23), frameon=False, fontsize=10)

    labels = ["One piece", "Two pieces", "Four pieces", "Square range"]
    uppers = [max(enclosure(x)[1] for x in pieces(n)) for n in (1, 2, 4)] + [Q(1, 4)]
    endpoint_labels = ["1", "1/2", "3/8", "1/4 (exact)"]
    for index, (upper, endpoint) in enumerate(zip(uppers, endpoint_labels)):
        color = "#bb3e28" if index == 3 else "#3479a7"
        bars.plot([0, float(upper)], [index, index], color=color, lw=8, solid_capstyle="butt")
        bars.scatter([0, float(upper)], [index, index], s=35, color=color, zorder=3)
        bars.text(float(upper) + 0.02, index, endpoint, va="center", color=color)
    bars.axvline(float(Q(1, 4)), ls=":", color="#bb3e28", lw=1.3)
    bars.set(title="Enclosure of the full output range", xlim=(-0.02, 1.14), ylim=(3.6, -0.7),
             yticks=range(4), yticklabels=labels, xticks=(0, 0.25, 0.5, 0.75, 1),
             xticklabels=("0", "1/4", "1/2", "3/4", "1"), xlabel="Output value")
    bars.tick_params(axis="y", length=0)
    for ax in (local, bars):
        ax.spines[["top", "right"]].set_visible(False)
    bars.spines["left"].set_visible(False)
    fig.subplots_adjust(left=0.14, right=0.96, bottom=0.09, top=0.87)
    fig.savefig(Path.cwd() / "interval-dependency-and-subdivision.png", facecolor="white", transparent=False)
    plt.close(fig)


if __name__ == "__main__":
    main()