codexnegative-feedback-delay-modes.py
negative-feedback-delay-modes.py
"""Synthetic modes of x' = -x - 2*x(t-d); no biological measurements.
Tested with Python 3.14.4, NumPy 2.3.5, Matplotlib 3.10.7.
Run from _media; write matching-basename opaque white PNG to CWD.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def characteristic_root(delay):
"""Follow the oscillatory branch from its first imaginary-axis crossing."""
critical = 2 * np.pi / (3 * np.sqrt(3))
z = 1j * np.sqrt(3)
for d in np.linspace(critical, delay, 100):
for _ in range(30):
step = (z + 1 + 2 * np.exp(-z * d)) / (1 - 2 * d * np.exp(-z * d))
z -= step
if abs(step) < 1e-14:
break
assert abs(z + 1 + 2 * np.exp(-z * delay)) < 1e-11
return z
def main():
plt.rcParams.update({"font.size": 11, "figure.facecolor": "white"})
critical = 2 * np.pi / (3 * np.sqrt(3))
fig = plt.figure(figsize=(10, 7), dpi=110)
grid = fig.add_gridspec(2, 1, height_ratios=(1, 3), hspace=0.24)
circuit = fig.add_subplot(grid[0])
circuit.set(xlim=(0, 10), ylim=(0, 3))
circuit.axis("off")
circuit.text(5, 2.6, "SYNTHETIC LINEAR MODEL — no biological data", ha="center", weight="bold")
for px, text in ((2, "Displacement x(t)"), (8, "Return after delay d")):
circuit.text(px, 1.4, text, ha="center", va="center", bbox={"boxstyle": "round,pad=0.6", "fc": "white", "ec": "#334155"})
circuit.annotate("", (6.4, 1.7), (3.5, 1.7), arrowprops={"arrowstyle": "->", "color": "#334155"})
circuit.text(5, 1.9, "+", ha="center")
circuit.annotate("", (3.5, 0.8), (6.4, 0.8), arrowprops={"arrowstyle": "-[", "color": "#334155"})
circuit.text(5, 0.10, "Negative return: −2x(t−d); local removal: −x(t)", ha="center")
ax = fig.add_subplot(grid[1])
t = np.linspace(0, 12, 2401)
ax.plot(t, np.exp(-3 * t), color="#475569", lw=2, label="d = 0: exponential decay")
for d, color, label in ((0.7, "#187c64", "d = 0.7: damped mode"), (critical, "#2468b4", f"d = {critical:.4f}: neutral mode"), (1.5, "#ba4a29", "d = 1.5: growing mode")):
z = characteristic_root(d)
ax.plot(t, np.exp(z.real * t) * np.cos(z.imag * t), color=color, lw=2, label=label)
ax.axhline(0, color="#94a3b8", lw=0.8)
ax.set(xlabel="Time t (normalized units)", ylabel="Signed displacement x(t)", xlim=(0, 12), ylim=(-2.7, 2.7))
ax.grid(alpha=0.2)
ax.legend(loc="upper left", ncol=2, fontsize=10, framealpha=1)
ax.text(0.99, 0.02, "Each curve uses its own matching exponential-mode history.\nGrowing oscillations are instability, not a bounded limit cycle.", transform=ax.transAxes, ha="right", va="bottom", fontsize=10, bbox={"fc": "white", "ec": "none"})
fig.subplots_adjust(left=0.10, right=0.97, bottom=0.10, top=0.96)
fig.savefig(Path.cwd() / (Path(__file__).stem + ".png"), facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()