codexdelay-equation-history-comparison.py
delay-equation-history-comparison.py
"""Compare exact futures from two histories; Python 3.14, NumPy 2.3, Matplotlib 3.10.
Run from _media; writes delay-equation-history-comparison.png in the CWD.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def future_a(t):
return 1 + t + np.maximum(t - 1, 0) ** 2 / 2
def future_b(t):
t = np.asarray(t)
u = t - 1
return np.where(t <= 1, 1 + t ** 2 / 2, 1.5 + u + u ** 3 / 6)
def main():
probes = np.array([0.2, 0.7, 1.2, 1.7])
delayed_b = np.where(probes < 1, probes, future_b(probes - 1))
derivative_b = np.where(probes < 1, probes, 1 + (probes - 1) ** 2 / 2)
assert np.allclose(delayed_b, derivative_b, rtol=0, atol=1e-14)
assert np.allclose(future_a(np.array([0, 1, 2])), [1, 2, 7 / 2])
assert np.allclose(future_b([0, 1, 2]), [1, 3 / 2, 8 / 3])
plt.rcParams.update({"font.size": 11, "axes.spines.top": False, "axes.spines.right": False})
fig, ax = plt.subplots(figsize=(8, 4.5), dpi=120, facecolor="white")
blue, orange = "#2468ad", "#c66b13"
past, future = np.linspace(-1, 0, 161), np.linspace(0, 2, 321)
ax.axvspan(-1, 0, color="#64748b", alpha=0.075)
ax.plot(past, np.ones_like(past), "--", color=blue, lw=2.6)
ax.plot(past, 1 + past, "--", color=orange, lw=2.6)
ax.plot(future, future_a(future), color=blue, lw=2.6, label=r"History A: $\phi_A(s)=1$")
ax.plot(future, future_b(future), color=orange, lw=2.6, label=r"History B: $\phi_B(s)=1+s$")
ax.axvline(0, color="#808080", lw=1)
ax.axvline(1, color="#808080", lw=0.8, ls=":")
ax.plot(0, 1, "o", ms=7, color="#263442", zorder=5)
ax.annotate("Same $y(0)=1$", (0, 1), xytext=(0.12, 0.4), fontsize=11,
arrowprops={"arrowstyle": "->", "color": "#263442"})
for t, ya, yb, la, lb in [(1, 2, 1.5, "$2$", "$3/2$"), (2, 3.5, 8 / 3, "$7/2$", "$8/3$")]:
for value, label, color, offset in [(ya, la, blue, 10), (yb, lb, orange, -18)]:
ax.plot(t, value, "o", color=color, ms=5)
ax.annotate(label, (t, value), xytext=(-5, offset), textcoords="offset points", ha="right", color=color)
ax.annotate("", (2.13, 3.5), xytext=(2.13, 8 / 3), arrowprops={"arrowstyle": "<->", "color": "#263442"})
ax.text(2.18, 37 / 12, "$5/6$", va="center", color="#263442")
ax.text(-0.5, 3.75, "Prescribed past", ha="center", fontsize=10, color="#525e6b")
ax.text(1, 3.75, "Exact future", ha="center", fontsize=10, color="#525e6b")
ax.set(xlim=(-1.08, 2.45), ylim=(-0.15, 4), xticks=[-1, 0, 1, 2],
xlabel="Time $t$ (delay = 1)", ylabel="$y(t)$")
ax.grid(axis="y", alpha=0.16)
ax.legend(loc="upper left", bbox_to_anchor=(0.02, 0.88), frameon=False, fontsize=10)
ax.set_title("One initial value does not specify the past: $y'(t)=y(t-1)$", pad=15, fontsize=13)
fig.subplots_adjust(left=0.09, right=0.975, bottom=0.14, top=0.86)
fig.savefig(Path(__file__).stem + ".png", facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()