codexrank-nullity-domain-decomposition.py
rank-nullity-domain-decomposition.py
"""A rank-one linear map decomposes input into visible and kernel components.
Python 3.14.4, NumPy 2.3.5, Matplotlib 3.10.7; opaque PNG to CWD.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def arrow(ax, a, b, color, label=None):
ax.annotate("", b, a, arrowprops={"arrowstyle": "-|>", "color": color,
"lw": 2.4, "mutation_scale": 16})
if label:
ax.text(*label[0], label[1], color=color, fontsize=11,
bbox={"facecolor": "white", "edgecolor": "none", "pad": 1})
def main():
A = np.array([[1, 2], [0, 0]])
visible, hidden = np.array([1, 2]), np.array([2, -1])
np.testing.assert_array_equal(A @ visible, [5, 0])
np.testing.assert_array_equal(A @ hidden, [0, 0])
fig, axes = plt.subplots(1, 2, figsize=(10.8, 4.8), dpi=120)
fig.patch.set_facecolor("white")
for ax in axes:
ax.set_facecolor("white")
ax.axhline(0, color="#bbbbbb", lw=1)
ax.axvline(0, color="#bbbbbb", lw=1)
ax.set_aspect("equal")
ax.grid(alpha=0.12)
t = np.linspace(-2.2, 2.2, 100)
axes[0].plot(2*t, -t, color="#2768a6", ls="--", lw=1.5,
label=r"Kernel: $x+2y=0$")
arrow(axes[0], [0, 0], visible, "#238367", ((0.0, 2.4), "Visible (1, 2)"))
arrow(axes[0], visible, [3, 1], "#2768a6",
((1.9, 1.9), "Kernel (2, −1)"))
arrow(axes[0], [0, 0], [3, 1], "#80519d",
((2.5, 0.3), "Input (3, 1)"))
axes[0].set(xlim=(-3, 4.4), ylim=(-2.1, 3.6), xlabel="Input x",
ylabel="Input y", title="Input: dimension 2")
axes[0].legend(loc="lower left", frameon=False, fontsize=10)
axes[1].plot([-1, 6], [0, 0], color="#238367", lw=3,
label="Image: horizontal line")
arrow(axes[1], [0, 0], [5, 0], "#80519d")
axes[1].scatter([0, 5], [0, 0], c=["#2768a6", "#80519d"], s=60, zorder=4)
axes[1].text(0, -0.6, "Kernel component\nmaps to zero",
ha="center", color="#2768a6", fontsize=11)
axes[1].text(5, 0.5, "Both inputs map\nto (5, 0)",
ha="center", color="#80519d", fontsize=11)
axes[1].set(xlim=(-1, 6), ylim=(-2.1, 3.6), xlabel="Output coordinate 1",
ylabel="Output coordinate 2", title="Output image: dimension 1")
axes[1].legend(loc="lower left", frameon=False, fontsize=10)
fig.suptitle(r"$T(x,y)=(x+2y,0)$: input dimension 2 = nullity 1 + rank 1",
fontsize=14, y=0.98)
fig.tight_layout(rect=(0, 0, 1, 0.91))
fig.savefig(Path.cwd() / Path(__file__).with_suffix(".png").name,
facecolor="white", transparent=False)
plt.close(fig)
if __name__ == "__main__":
main()