codex/dual-norm-unit-balls-supporting-lines.py

dual-norm-unit-balls-supporting-lines.py
"""Draw three unit balls and exact support points; output matching PNG in CWD."""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np


def main():
    theta = np.linspace(0, 2*np.pi, 721)
    boundaries = [np.array([[1,0],[0,1],[-1,0],[0,-1]]), np.column_stack([np.cos(theta),np.sin(theta)]), np.array([[1,1],[-1,1],[-1,-1],[1,-1]])]
    a = np.array([2.,-1.])
    points = [np.array([1.,0.]), a/np.sqrt(5), np.array([1.,-1.])]
    bounds = [2.,np.sqrt(5),3.]
    labels = [r"$\|x\|_1\leq1$",r"$\|x\|_2\leq1$",r"$\|x\|_\infty\leq1$"]
    values = [r"$\|p\|_*=2$",r"$\|p\|_*=\sqrt{5}$",r"$\|p\|_*=3$"]
    fig, axes = plt.subplots(1,3,figsize=(12.3,4.6),dpi=120)
    fig.patch.set_facecolor("white")
    for ax,boundary,point,bound,label,value in zip(axes,boundaries,points,bounds,labels,values):
        assert np.isclose(a @ point,bound)
        ax.add_patch(Polygon(boundary,closed=True,facecolor="#dcebf2",edgecolor="#28738f",lw=2))
        t = np.linspace(-1.4,1.4,100)
        ax.plot(t,2*t-bound,color="#bf6529",lw=2,label="supporting line")
        ax.scatter(*point,color="#bf6529",s=55,zorder=5)
        ax.axhline(0,color="#aaaaaa",lw=.6)
        ax.axvline(0,color="#aaaaaa",lw=.6)
        ax.grid(color="#e5e5e5",lw=.5)
        ax.set(xlim=(-1.38,1.38),ylim=(-1.38,1.38),xlabel=r"$x_1$",ylabel=r"$x_2$")
        ax.set_aspect("equal")
        ax.set_xticks([-1,0,1]);ax.set_yticks([-1,0,1])
        ax.set_title(label+"\n"+value,fontsize=15,pad=14)
        ax.spines[["top","right"]].set_visible(False)
    fig.suptitle(r"The same functional $p(x)=2x_1-x_2$, three input unit balls",fontsize=18,weight="bold")
    fig.text(.5,.035,r"Orange line: $2x_1-x_2=\|p\|_*$.  Its marked contact point attains the maximum.",ha="center",fontsize=12)
    fig.subplots_adjust(left=.055,right=.975,top=.73,bottom=.17,wspace=.28)
    fig.savefig(Path(__file__).stem+".png",facecolor="white",transparent=False)
    plt.close(fig)


if __name__ == "__main__":
    main()