generate_figures.py
Large Signal Model
generate_figures.py
This is the original source text. Reading it does not run or verify the program.
1 r"""Exact mathematical diagrams for the LSM theoretical atlas. No empirical data."""
2 from pathlib import Path
3 from fractions import Fraction as F
4 import json
5 import numpy as np
6 import matplotlib
7 matplotlib.use(r'Agg')
8 import matplotlib.pyplot as plt
9 from matplotlib.patches import FancyArrowPatch, Rectangle, Polygon, Ellipse
10
11 ROOT=Path(__file__).resolve().parent
12 OUT=ROOT/r'figures'; OUT.mkdir(exist_ok=True)
13 INK=r'#253249'; TEAL=r'#146b72'; GOLD=r'#aa7832'; RED=r'#aa5146'; PALE=r'#edf3f4'; GREY=r'#667281'
14 plt.rcParams.update({r'font.family':r'DejaVu Serif',r'font.size':10,r'mathtext.fontset':r'stix',r'axes.spines.top':False,r'axes.spines.right':False,r'axes.labelcolor':INK,r'text.color':INK,r'xtick.color':GREY,r'ytick.color':GREY,r'axes.edgecolor':r'#aab2bc',r'pdf.fonttype':42,r'savefig.facecolor':r'white'})
15
16 def fig(name,w=7.1,h=2.8):
17 f,ax=plt.subplots(figsize=(w,h));return f,ax
18
19 def save(f,name):
20 f.savefig(OUT/(name+r'.pdf'),bbox_inches=r'tight',pad_inches=.13)
21 plt.close(f)
22
23 def base(ax):ax.set_xlim(0,10);ax.set_ylim(0,4);ax.axis(r'off')
24 def box(ax,x,y,w,h,label,c=TEAL):
25 ax.add_patch(Rectangle((x,y),w,h,facecolor=PALE,edgecolor=c,lw=1.2))
26 ax.text(x+w/2,y+h/2,label,ha=r'center',va=r'center',fontsize=11,color=INK)
27 def arr(ax,p,q,label=r'',color=INK,rad=0):
28 ax.add_patch(FancyArrowPatch(p,q,arrowstyle=r'-|>',mutation_scale=12,lw=1.2,color=color,connectionstyle=f'arc3,rad={rad}'))
29 if label:
30 ax.text((p[0]+q[0])/2,(p[1]+q[1])/2+.17,label,ha=r'center',va=r'bottom',fontsize=10,color=color)
31
32 # A compact, typed architecture: different contracts share one underlying object.
33 f,ax=fig(r'00_architecture',h=2.7);base(ax)
34 box(ax,.1,2.65,2.15,.75,r'Observation $x\in X$')
35 box(ax,3.9,2.65,2.15,.75,r'Archive $c\in\mathcal{C}$')
36 box(ax,7.75,2.65,2.15,.75,r'State $z\in Z$')
37 arr(ax,(2.3,3.05),(3.85,3.05),r'analysis $A$')
38 arr(ax,(6.1,3.05),(7.7,3.05),r'summary $\gamma S$')
39 box(ax,.1,.45,2.15,.75,r'Transition $F_u x$')
40 box(ax,3.9,.45,2.15,.75,r'Realization $A F_u x$')
41 box(ax,7.75,.45,2.15,.75,r'Prediction $\bar F_u z$')
42 arr(ax,(1.15,2.55),(1.15,1.3),r'$F_u$',TEAL)
43 arr(ax,(4.95,2.55),(4.95,1.3),r'$F_{u,A}$',TEAL)
44 arr(ax,(8.8,2.55),(8.8,1.3),r'$\bar F_u$',TEAL)
45 arr(ax,(2.3,.85),(3.85,.85),r'$A$')
46 arr(ax,(6.1,.85),(7.7,.85),r'$\gamma S$')
47 ax.text(5,-.05,r'Left square: coordinate consistency. Right square: predictive closure.',ha=r'center',fontsize=10)
48 save(f,r'00_architecture')
49
50 # Redundant coefficient plane and an oblique consistency projector.
51 f=plt.figure(figsize=(7.1,3.1));ax=f.add_subplot(111,projection=r'3d')
52 a,b=np.meshgrid(np.linspace(-.7,1.6,10),np.linspace(-.5,1.3,10))
53 ax.plot_surface(a,b,a+b,alpha=.17,color=TEAL,linewidth=0)
54 q=np.array([1,.35,1.95]);pq=np.array([1,.35,1.35]);ax.scatter(*q,color=RED,s=34);ax.scatter(*pq,color=TEAL,s=34)
55 ax.plot(*np.array([q,pq]).T,color=RED,lw=1.7)
56 ax.text(*q,r' $c$',color=RED);ax.text(*pq,r' $\Pi c$',color=TEAL)
57 ax.set(xlabel=r'$c_1$',ylabel=r'$c_2$',zlabel=r'$c_3$');ax.view_init(22,-58)
58 ax.set_box_aspect((1,1,1));ax.grid(False);f.subplots_adjust(left=0,right=.95,bottom=.05,top=1)
59 save(f,r'01_consistency')
60
61 f,ax=fig(r'02_transport',h=2.65);base(ax)
62 for x,y,label in [(.3,2.7,r'$c_a=A_a x$'),(7.1,2.7,r'$c_b=A_b x$'),(.3,.5,r'$F_a c_a$'),(7.1,.5,r'$F_b c_b$')]:box(ax,x,y,2.6,.8,label)
63 arr(ax,(3,3.1),(7,3.1),r'$T_{ba}=A_bS_a$')
64 arr(ax,(3,.9),(7,.9),r'$T_{ba}$')
65 arr(ax,(1.6,2.6),(1.6,1.4),r'$F_a$');arr(ax,(8.4,2.6),(8.4,1.4),r'$F_b$')
66 ax.text(5,1.95,r'$F_bT_{ba}=T_{ba}F_a$',ha=r'center',fontsize=16,color=TEAL)
67 save(f,r'02_transport')
68
69 L=np.array([[.5,1],[.25,1/3]])
70 f,(ax1,ax2)=plt.subplots(1,2,figsize=(7.1,2.8),sharex=True,sharey=True)
71 ys=np.linspace(-1.3,1.3,40)
72 for ax in [ax1,ax2]:
73 ax.axhline(0,color=r'#cad0d7',lw=.7);ax.axvline(0,color=r'#cad0d7',lw=.7)
74 ax.set(xlim=(-1.5,1.5),ylim=(-1.5,1.5),xlabel=r'retained coordinate $y$',ylabel=r'unresolved coordinate $w$')
75 ax1.plot(np.zeros_like(ys),ys,color=TEAL,lw=2)
76 ax1.scatter([0,0],[0,1],color=[INK,RED],zorder=5,s=36)
77 ax1.text(.12,1,r'$x^\prime=(0,1)$',fontsize=10);ax1.text(.12,.03,r'$x=(0,0)$',fontsize=10)
78 ax1.set_title(r'One summary, two states',fontsize=11)
79 ax2.plot(ys,ys/3,color=TEAL,lw=2);ax2.scatter([0,1],[0,1/3],color=[INK,RED],s=36,zorder=5)
80 ax2.text(.22,.65,r'$\gamma Lx^\prime=1$',color=RED);ax2.text(-1.4,-1.25,r'$L(\ker\gamma)\not\subseteq\ker\gamma$',fontsize=12)
81 ax2.set_title(r'Different next summaries',fontsize=11)
82 f.tight_layout(w_pad=2);save(f,r'03_fibers')
83
84 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,2.6))
85 a1.set(xlim=(-.2,1.4),ylim=(-.2,1.4),xlabel=r'first observable coefficient',ylabel=r'second observable coefficient')
86 a1.axhline(0,color=TEAL,lw=2);a1.arrow(0,0,.5,1,head_width=.05,color=GOLD,length_includes_head=True)
87 a1.text(.65,.85,r'$CL=(1/2,1)$',fontsize=11);a1.text(.5,.08,r'$W_0=\mathrm{span}\{C\}$',fontsize=10)
88 a1.set_title(r'Pull back the observable',fontsize=11)
89 a2.axis(r'off');a2.text(.04,.82,r'$W_0=\mathrm{span}\{(1,0)\}$',fontsize=15)
90 a2.text(.04,.53,r'$W_1=\mathrm{span}\{(1,0),(1/2,1)\}$',fontsize=14,color=TEAL)
91 a2.text(.04,.22,r'$W_1=\mathbb{R}^{2\,*}=W_*$',fontsize=16)
92 f.tight_layout();save(f,r'04_refinement')
93
94 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,2.7))
95 a1.imshow(L,cmap=r'Blues',vmin=0,vmax=1)
96 for (i,j),v in np.ndenumerate(L):a1.text(j,i,[[r'$1/2$',r'$1$'],[r'$1/4$',r'$1/3$']][i][j],ha=r'center',va=r'center',fontsize=16,color=r'white' if v>.6 else INK)
97 a1.set_xticks([0,1],[r'input $P_1$',r'input $P_2$']);a1.set_yticks([0,1],[r'output $P_1$',r'output $P_2$']);a1.set_title(r'Linear transfer blocks $P_jLP_i$',fontsize=11)
98 u=1.;v=np.linspace(0,.4,100);a2.plot(v,2*u*v,color=RED,label=r'mixed term $2uv$',lw=2);a2.plot(v,v*v,color=TEAL,label=r'packet square $v^2$',lw=2)
99 a2.set(xlabel=r'omitted amplitude $v$ with $u=1$',ylabel=r'contribution to $(u+v)^2$');a2.legend(frameon=False,fontsize=9,loc=r'upper left');a2.set_title(r'Nonlinear influence has a cross term',fontsize=11)
100 f.tight_layout(w_pad=2.5);save(f,r'05_packets')
101
102 f,ax=fig(r'06_return_path',h=2.2);base(ax)
103 box(ax,.1,1.3,2.25,1.05,'Retained\n$Pe_1=e_1$')
104 box(ax,3.85,1.3,2.25,1.05,'Unresolved\n$Qe_2=e_2$',GOLD)
105 box(ax,7.6,1.3,2.25,1.05,'Retained\n$Pe_1=e_1$')
106 arr(ax,(2.5,1.85),(3.7,1.85),r'$M$',GOLD);arr(ax,(6.25,1.85),(7.45,1.85),r'$L$',GOLD)
107 ax.text(5,.45,r'Separate compression deletes both arrows. Composition retains their return path.',ha=r'center',fontsize=10)
108 save(f,r'06_return_path')
109
110 # Canonical exact rational trajectory, memory coefficients and exact checks.
111 LF=[[F(1,2),F(1)],[F(1,4),F(1,3)]]
112 x=[F(1),F(0)];records=[]
113 for t in range(13):
114 records.append([str(x[0]),str(x[1])]);x=[sum(LF[i][j]*x[j] for j in range(2)) for i in range(2)]
115 y=[F(row[0]) for row in records]
116 for t in range(11):assert y[t+2]==F(5,6)*y[t+1]+F(1,12)*y[t]
117 for t in range(12):
118 memory=F(1,2)*y[t]+sum(F(1,4)*F(1,3)**j*y[t-1-j] for j in range(t))
119 assert y[t+1]==memory
120 assert y[:5]==[F(1),F(1,2),F(1,2),F(11,24),F(61,144)]
121 (OUT/r'exact_example.json').write_text(json.dumps({r'matrix':[[str(x) for x in row] for row in LF],r'initial_state':[r'1',r'0'],r'trajectory':records,r'checked_recurrence_steps':11,r'checked_memory_steps':12,r'probability_data':False},indent=2)+'\n')
122 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,2.65))
123 j=np.arange(8);a1.stem(j,.25*(1/3.)**j,linefmt=TEAL,markerfmt=r'o',basefmt=r' ');a1.set(xlabel=r'lag $j$',ylabel=r'$K_j=(1/4)(1/3)^j$');a1.set_title(r'Exact projected memory kernel',fontsize=11)
124 t=np.arange(13);a2.plot(t,[float(x) for x in y],r'-o',color=TEAL,ms=4,label=r'exact dynamics / full memory')
125 a2.plot(t,.5**t,r'--',color=RED,label=r'one-coordinate compression')
126 a2.set(xlabel=r'step $t$',ylabel=r'resolved output $y_t$');a2.legend(frameon=False,fontsize=8.5);a2.set_title(r'The lost history changes prediction',fontsize=11)
127 f.tight_layout(w_pad=2);save(f,r'07_memory')
128
129 f,ax=fig(r'08_defect',h=2.7)
130 t=np.arange(21);delta=.02
131 for rho,col,lab in [(.7,TEAL,r'$\rho=0.7$'),(1,GOLD,r'$\rho=1$'),(1.08,RED,r'$\rho=1.08$')]:
132 bound=delta*t if rho==1 else delta*(rho**t-1)/(rho-1)
133 ax.plot(t,bound,lw=2,color=col,label=lab)
134 ax.set(xlabel=r'composition length $T$',ylabel=r'propagated upper bound');ax.legend(frameon=False,loc=r'upper left');ax.text(.98,.02,r'Analytical bounds with $e_0=0$, $\delta_t=0.02$',transform=ax.transAxes,ha=r'right',fontsize=9,color=GREY)
135 f.tight_layout();save(f,r'08_defect')
136
137 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,2.65))
138 zm=np.array([[1,.5],[.5,.5]]);zp=np.array([[.5,.5],[.5,11/24]])
139 a1.scatter(zm[0],zm[1],color=TEAL,s=55);a1.scatter(zp[0],zp[1],color=GOLD,s=45)
140 for i in range(2):arr(a1,zm[:,i],zp[:,i],color=TEAL)
141 a1.set(xlim=(.2,1.12),ylim=(.2,.7),xlabel=r'$y_{t-1}$',ylabel=r'$y_t$');a1.set_title(r'Two independent history states',fontsize=11)
142 a2.axis(r'off');a2.text(.02,.84,r'Input and successor windows',fontsize=16)
143 a2.text(.02,.49,r'$\det Z_-=1/4$',fontsize=16,color=TEAL)
144 a2.text(.02,.15,r'$D_2=Z_+Z_-^{-1}$',fontsize=16)
145 f.tight_layout(w_pad=3);save(f,r'09_identification')
146
147 f,ax=fig(r'10_domain',h=2.65);base(ax)
148 box(ax,.05,1.3,2.2,1,r'$z\in K$'+'\n'+r'$\lambda z=1$')
149 box(ax,3.8,1.3,2.4,1,r'$B_o z\in C$'+'\nunnormalized')
150 box(ax,7.75,1.3,2.2,1,r'$z_o\in K$'+'\nposterior')
151 arr(ax,(2.4,1.8),(3.65,1.8),r'$B_o$')
152 arr(ax,(6.35,1.8),(7.6,1.8),r'$/(\lambda B_o z)$')
153 ax.text(5,.45,r'$p_o=\lambda B_o z\geq0,\qquad\sum_o p_o=1$',ha=r'center',fontsize=15,color=TEAL)
154 ax.text(5,3.25,r'Cone preservation gives positivity. The mass identity gives normalization.',ha=r'center',fontsize=10)
155 save(f,r'10_domain')
156
157 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,3))
158 theta=np.linspace(0,2*np.pi,300);a1.fill(np.cos(theta),np.sin(theta),facecolor=PALE,edgecolor=TEAL,lw=1.5)
159 R=np.array([[3/5,-4/5],[4/5,3/5]]);v=np.array([1.,0]);points=[]
160 for _ in range(18):points.append(v.copy());v=R@v
161 points=np.array(points);a1.plot(points[:,0],points[:,1],r'-o',color=GOLD,ms=3,lw=.8)
162 a1.set(xlabel=r'$x$',ylabel=r'$y$',aspect=r'equal',xlim=(-1.17,1.17),ylim=(-1.17,1.17));a1.set_title(r'Normalized Lorentz slice: a disk',fontsize=11)
163 a2.axis(r'off');a2.text(.05,.8,r'$m\geq\sqrt{x^2+y^2}$',fontsize=18,color=TEAL)
164 a2.text(.05,.53,r'$\det J=(m^2-x^2-y^2)/4$',fontsize=17)
165 a2.text(.05,.2,r'$\lambda_{\pm}(J)=(m\pm\sqrt{x^2+y^2})/2$',fontsize=15)
166 f.tight_layout(w_pad=2);save(f,r'11_psd')
167
168 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,2.65))
169 u=np.linspace(-1,1,200);a1.plot(u,u*u,color=TEAL,lw=2,label=r'$u^2$');a1.scatter([0],[0],color=RED,s=42,zorder=5)
170 a1.axhline(1/3,color=GOLD,lw=1.5,ls=r'--',label=r'$\mathbb{E}[U^2]=1/3$');a1.set(xlabel=r'$u$ under uniform $[-1,1]$',ylabel=r'quadratic contribution');a1.legend(frameon=False,fontsize=9)
171 a2.axis(r'off');a2.text(.03,.82,r'$\bar K=\mathbb{E}[K(U)]$',fontsize=15)
172 a2.text(.03,.51,r'$\mathbb{E}[KXK^{\mathsf{T}}]-\bar KX\bar K^{\mathsf{T}}$',fontsize=15,color=TEAL)
173 a2.text(.03,.2,r'$=\mathrm{Var}(U)\,K_1XK_1^{\mathsf{T}}$',fontsize=15)
174 f.tight_layout(w_pad=2);save(f,r'12_covariance')
175
176 f=plt.figure(figsize=(7.1,3.1));a1=f.add_subplot(121);a2=f.add_subplot(122,projection=r'3d')
177 u=np.linspace(-1,1,200);a1.fill_between(u,u*u,1,color=PALE);a1.plot(u,u*u,color=TEAL,lw=2);a1.plot([-1,1],[1,1],color=TEAL,lw=1.3);a1.scatter([-.7,.3],[.49,.09],color=GOLD,s=32);a1.set(xlabel=r'first moment $x$',ylabel=r'second moment $y$',ylim=(-.05,1.08));a1.set_title(r'Normalized slice $x^2\leq y\leq1$',fontsize=11)
178 for m in np.linspace(.18,1,6):a2.plot(np.full_like(u,m),m*u,m*u*u,color=TEAL,lw=.65);a2.plot([m,m],[-m,m],[m,m],color=TEAL,lw=.5)
179 for v in np.linspace(-1,1,9):
180 m=np.linspace(0,1,50);a2.plot(m,m*v,m*v*v,color=TEAL,lw=.5)
181 a2.set(xlabel=r'$m$',ylabel=r'$x$',zlabel=r'$y$');a2.view_init(22,-57);a2.set_title(r'Homogeneous moment cone',fontsize=11);a2.grid(False)
182 f.subplots_adjust(left=.08,right=.96,bottom=.17,top=.88,wspace=.28);save(f,r'13_moments')
183
184 f,(a1,a2)=plt.subplots(1,2,figsize=(7.1,2.7))
185 a1.add_patch(Polygon([(1,0),(0,1),(-1,0),(0,-1)],facecolor=PALE,edgecolor=TEAL,lw=1.5))
186 a1.add_patch(Rectangle((.1,-.16),.24,.28,edgecolor=GOLD,facecolor=r'#e9d8b6',alpha=.8,lw=1.3));a1.scatter([.22],[-.02],color=GOLD,s=30)
187 a1.set(xlim=(-1.1,1.1),ylim=(-1.1,1.1),aspect=r'equal',xlabel=r'$a$',ylabel=r'$b$');a1.set_title(r'A whole parameter set is certified',fontsize=11)
188 a2.axis(r'off');a2.text(.02,.85,r'$p_{a,b}(u\mid x,y)$',fontsize=17)
189 a2.text(.02,.64,r'$=1+axu+byL_2(u)$',fontsize=16)
190 a2.text(.02,.35,r'$\inf p\geq1-\sup_{(a,b)\in\Theta}(|a|+|b|)$',fontsize=14,color=TEAL)
191 a2.text(.02,.07,r'Schematic set inclusion, not observed confidence coverage.',fontsize=8.5,color=GREY)
192 f.tight_layout(w_pad=2);save(f,r'14_uncertainty')
193
194 f,ax=fig(r'15_horizons',h=2.75)
195 t=np.arange(0,51);Delta=1/50;rho=1/4
196 ax.plot(t,np.minimum(1,t*Delta),color=GOLD,lw=2,label=r'full-record bound $\min(1,T\Delta)$')
197 ax.plot(t,Delta*(1-(1-rho)**t)/rho,color=TEAL,lw=2,label=r'one-time bound $\Delta[1-(1-\rho)^t]/\rho$')
198 ax.axhline(Delta/rho,color=TEAL,ls=r':',lw=1)
199 ax.set(xlabel=r'future length / time $T$',ylabel=r'total variation upper bound',ylim=(0,1.04));ax.legend(frameon=False,fontsize=9,loc=r'upper left');ax.text(.98,.15,r'Analytical illustration: $\Delta=1/50$, $\rho=1/4$, $e_0=0$',transform=ax.transAxes,ha=r'right',fontsize=9,color=GREY)
200 f.tight_layout();save(f,r'15_horizons')
201 print(json.dumps({r'figures':len(list(OUT.glob(r'*.pdf'))),r'exact_arithmetic_checks':r'passed',r'empirical_claims':False}))
Other PDFs for this work
Original file and source record
This copy matches the recorded source file. Its publication here does not change the work’s review status.
SHA-256: a881bb7763522167374683fe45965fff75cc6d9ccee49398c35bd78f7b2d440f