codex/adaptive-clearance-sampling.py

adaptive-clearance-sampling.py
"""Exact point-path clearance and adaptive Lipschitz certificates; PNG in cwd."""
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt


def certify(delta=.01,margin=.005):
    sampled={}
    intervals=[]
    def query(t):
        if t not in sampled:sampled[t]=float(np.hypot(t-.5,delta))
        return sampled[t]
    def visit(a,b,depth=0):
        assert depth<=24
        lower=min(query(a),query(b))-(b-a)/2
        if lower>margin:
            intervals.append((a,b,lower));return
        midpoint=(a+b)/2
        assert query(midpoint)>margin
        visit(a,midpoint,depth+1);visit(midpoint,b,depth+1)
    visit(0.,1.)
    return sampled,intervals


def main():
    sampled,intervals=certify()
    assert min(np.hypot(-.5,.01),np.hypot(.5,.01))-.5 < .005
    assert len(sampled)>2
    assert np.isclose(sum(b-a for a,b,_ in intervals),1)
    for a,b,lower in intervals:
        assert lower>.005
        exact_min=np.hypot(np.clip(.5,a,b)-.5,.01)
        assert lower<=exact_min+1e-14
    widths=[(b-a,(a+b)/2)for a,b,_ in intervals]
    assert min(h for h,t in widths if abs(t-.5)<.1)<max(h for h,t in widths if abs(t-.5)>.3)
    t=np.linspace(0,1,2001)
    times=np.array(sorted(sampled))
    fig,axes=plt.subplots(1,2,figsize=(9.6,4),dpi=100,facecolor='white')
    axes[0].plot(t,np.hypot(t-.5,.01),color='#333333',lw=1.7,label='Exact constructed clearance')
    axes[0].scatter(times,[sampled[x]for x in times],color='#2475ad',s=25,label=f'{len(sampled)} queried times',zorder=3)
    axes[0].axhline(.005,color='#b63f32',ls='--',lw=1,label='Required clearance: 0.005 m')
    for i,(a,b,lower)in enumerate(intervals):
        axes[0].plot([a,b],[lower,lower],color='#38824d',lw=2,label='Certified interval lower bound'if i==0 else None)
    axes[0].set(xlabel='Time (s)',ylabel='Clearance (m)',title='Conservative bounds certify the whole path',ylim=(0,.55))
    axes[0].legend(fontsize=8,loc='upper center')
    for a,b,_ in intervals:axes[1].plot([a,b],[b-a,b-a],color='#2475ad',lw=3)
    axes[1].set_yscale('log',base=2)
    axes[1].set(xlabel='Time (s)',ylabel='Certified interval duration (s)',title='Shorter intervals near closest approach')
    for ax in axes:ax.grid(alpha=.2)
    fig.tight_layout()
    fig.savefig(Path.cwd()/(Path(__file__).stem+'.png'),facecolor='white')
    plt.close(fig)
    print(f'{len(sampled)} sample queries; {len(intervals)} certified intervals; minimum true clearance = 0.01 m')


if __name__=='__main__':
    main()