High-precision refinement of the Italian opera time weights

Same data and default penalty · resolving weakly regularized directions

Why refine these cases

Three Italian opera specifications have different double-precision QP weights from different initializers despite very small objective gaps. At the default penalty, the objective is almost flat along some weight directions. All eleven nondegenerate opera blocks are therefore solved at 80 decimal digits, rather than refining only the three most conspicuous cases. Default tuning is retained. The representative example selected before fitting is unchanged.

This is a primal active-set solution of the same nonnegative, unit-sum quadratic program. The intercept is profiled out by centering across donors. The intended least-squares objective is evaluated in high precision using the same stored outcome values; the default noise-scale recipe is unchanged. The tiny rounding difference in its evaluation is checked against the original saved penalty. Every solution is checked for feasibility and the simplex dual gap. The three initializer-sensitive cases are solved again from the default weights.

Code
import csv, json, math, time
from pathlib import Path
import mpmath as mp
import numpy as np
mp.mp.dps=80
root=Path.cwd().parents[1]
inputs=root/'analyses/sdid-time-weights-default/inputs'
def read(path):
    with open(path) as f:return list(csv.DictReader(f))
manifest={r['fit_id']:r for r in read(inputs/'manifest.csv')}
base=read('fits.csv'); vectors=read('time-weights.csv')
original={r['fit_id']:r for r in read('../sdid-time-weights-default/fits.csv')}
initial=read('initialization-sensitivity.csv')
sensitive={r['fit_id'] for r in initial if float(r['l1_difference'])>1e-3}
lookup={}
for r in vectors:lookup.setdefault((r['fit_id'],r['method']),[]).append(float(r['lambda']))

def solve(H,g,start):
    n=len(g);tol=mp.mpf('1e-55')
    x=mp.matrix([mp.mpf(float(v)) for v in start]);x=x/sum(x)
    S=[i for i in range(n) if x[i]>0]
    for it in range(1000):
        k=len(S);K=mp.matrix(k+1);rhs=mp.matrix(k+1,1)
        for i,ii in enumerate(S):
            rhs[i]=g[ii];K[i,k]=1;K[k,i]=1
            for j,jj in enumerate(S):K[i,j]=H[ii,jj]
        rhs[k]=1
        ans=mp.lu_solve(K,rhs)
        y=mp.matrix(n,1)
        for i,ii in enumerate(S):y[ii]=ans[i]
        negative=[i for i in S if y[i]<-tol]
        if negative:
            alpha=min(x[i]/(x[i]-y[i]) for i in negative)
            x=x+alpha*(y-x)
            for i in S:
                if abs(x[i])<tol:x[i]=0
            S=[i for i in S if x[i]>0]
            continue
        x=y
        gradient=2*(H*x-g)
        mu=sum(gradient[i] for i in S)/len(S)
        outside=[i for i in range(n) if i not in S]
        if not outside or min(gradient[i]-mu for i in outside)>=-tol:
            gap=sum(x[i]*gradient[i] for i in range(n))-min(gradient)
            assert min(x)>=-tol and abs(sum(x)-1)<tol and abs(gap)<mp.mpf('1e-50')
            return x,max(mp.mpf(0),gap),it+1
        S.append(min(outside,key=lambda i:gradient[i]))
    raise RuntimeError('Active-set iteration limit')

refined={};receipts=[];export=[]
for r in [r for r in base if r['method']=='qp_uniform' and r['paper_id']=='study-08']:
    tic=time.time();fid=r['fit_id'];m=manifest[fid];n=int(m['T0'])
    units=read(inputs/m['units_file'])
    with (inputs/m['matrix_file']).open() as f:all_y=list(csv.reader(f))
    # Convert via binary64 to use exactly the same stored outcome values as R.
    Y=[[mp.mpf(float(v)) for v in row] for row,u in zip(all_y,units) if int(u['first_treated_column_zero_based'])==-1]
    N=len(Y);P=len(Y[0])-n
    diffs=[row[t]-row[t-1] for row in Y for t in range(1,n)]
    dm=sum(diffs)/len(diffs);sigma=mp.sqrt(sum((v-dm)**2 for v in diffs)/(len(diffs)-1))
    zeta=mp.mpf('1e-6')*sigma
    assert abs(float(zeta)/float(original[fid]['zeta_lambda'])-1)<1e-12
    means=[sum(Y[i][t] for i in range(N))/N for t in range(n)]
    target=[sum(row[n:])/P for row in Y];target_mean=sum(target)/N
    A=mp.matrix([[(row[t]-means[t])/sigma for t in range(n)] for row in Y])
    b=mp.matrix([(v-target_mean)/sigma for v in target])
    H=A.T*A/N+mp.eye(n)*mp.mpf('1e-12');g=A.T*b/N
    x,gap,it=solve(H,g,[1/n]*n)
    init_diff=mp.mpf(0)
    if fid in sensitive:
        xx,gg,ii=solve(H,g,lookup[fid,'default'])
        init_diff=sum(abs(x[i]-xx[i]) for i in range(n))
        assert init_diff<mp.mpf('1e-45')
    xf=np.asarray([float(v) for v in x]);xf[np.abs(xf)<1e-50]=0;xf/=xf.sum()
    Af=np.asarray(A.tolist(),dtype=float);bf=np.asarray(list(b),dtype=float)
    gradient=2*Af.T@(Af@xf-bf)/N+2e-12*xf
    double_gap=max(0.,float(xf@gradient-gradient.min()))
    default=np.asarray(lookup[fid,'default']);qpu=np.asarray(lookup[fid,'qp_uniform'])
    obj=float(mp.fsum(v*v for v in A*x-b)/N+mp.mpf('1e-12')*mp.fsum(v*v for v in x))
    rr=dict(r);rr.update(method='qp_reference',objective=obj,gap=double_gap,accepted='TRUE',iterations=it,
        iteration_cap='FALSE',solver_status='80-digit active-set KKT verified',raw_violation=0,repair_l1=0,
        seconds=time.time()-tic,l1_from_default=float(np.abs(xf-default).sum()),
        max_change_from_default=float(np.abs(xf-default).max()),
        donor_prediction_rms_change=float(np.sqrt(np.mean((Af@(xf-default))**2))),
        support_1e6=int((xf>1e-6).sum()),effective_periods=float(1/(xf@xf)),
        mass_recent=float(xf[-math.ceil(.2*n):].sum()),mean_position=float(xf@np.linspace(0,1,n)))
    refined[fid]=rr
    template=[w for w in vectors if w['fit_id']==fid and w['method']=='qp_uniform']
    for j,w in enumerate(template):export.append(dict(w,method='qp_reference',lambda_value=float(xf[j]),raw_lambda=float(xf[j])))
    receipts.append({'fit_id':fid,'digits':80,'active_set_steps':it,'mp_gap':mp.nstr(gap,30),
      'initializer_check':fid in sensitive,'mp_initializer_l1':mp.nstr(init_diff,30),
      'l1_from_double_qp':float(np.abs(xf-qpu).sum()),'max_from_double_qp':float(np.abs(xf-qpu).max()),
      'rounded_double_gap':double_gap,'support_1e6':int((xf>1e-6).sum())})
    print(fid,'support',int((xf>1e-6).sum()),'L1 from double QP',float(np.abs(xf-qpu).sum()),flush=True)

def write(name,rows):
    with open(name,'w') as f:
        w=csv.DictWriter(f,fieldnames=list(rows[0]));w.writeheader();w.writerows(rows)
# The reference uses high precision for opera and the independently checked
# double QP for the remaining papers. The original five variants stay unchanged.
reference=[];reference_weights=[]
for r in [r for r in base if r['method']=='qp_uniform']:
    fid=r['fit_id'];rr=refined.get(fid,dict(r,method='qp_reference'))
    rr['precision_digits']=80 if fid in refined else 16
    reference.append(rr)
for w in vectors:
    if w['method']=='qp_uniform' and w['fit_id'] not in refined:reference_weights.append(dict(w,method='qp_reference'))
for w in export:
    w['lambda']=w.pop('lambda_value');reference_weights.append(w)
write('reference-fits.csv',reference);write('reference-weights.csv',reference_weights)
write('precision-checks.csv',receipts)
Path('precision-verification.json').write_text(json.dumps({'refined_fits':len(refined),'digits':80,
    'initializer_checks':len(sensitive),'all_mp_gaps_below':'1e-50',
    'all_checked_initializer_l1_below':'1e-45','mpmath_version':mp.__version__},indent=2)+'\n')
S08-P001--y__d--c032 support 4 L1 from double QP 0.380471979684898
S08-P001--y__d--c057 support 2 L1 from double QP 1.4988010832439613e-15
S08-P001--y__d--c059 support 3 L1 from double QP 7.077671781985373e-16
S08-P002--y__d--c032 support 27 L1 from double QP 1.1241008231145671e-15
S08-P002--y__d--c057 support 56 L1 from double QP 0.29301336021290236
S08-P002--y__d--c059 support 58 L1 from double QP 0.3432996080329836
S08-P003--y__d--c032 support 30 L1 from double QP 4.0939474033052647e-16
S08-P003--y__d--c057 support 56 L1 from double QP 0.07927535704653783
S08-P003--y__d--c059 support 58 L1 from double QP 0.09735706422830692
S08-P004--y__d--c057 support 56 L1 from double QP 3.1086244689504383e-15
S08-P004--y__d--c059 support 58 L1 from double QP 1.807581861967833e-15
176

Results

fit_id digits active_set_steps mp_gap initializer_check mp_initializer_l1 l1_from_double_qp max_from_double_qp rounded_double_gap support_1e6
0 S08-P001--y__d--c032 80 3 1.35156383887473700596676800638e-81 True 1.20701527045275894828870080117e-74 3.804720e-01 9.538023e-02 4.902470e-16 4
1 S08-P001--y__d--c057 80 10 2.10843958864610464486971481025e-81 False 0.0 1.498801e-15 7.771561e-16 1.110223e-16 2
2 S08-P001--y__d--c059 80 11 8.23609214314884626902232347755e-83 False 0.0 7.077672e-16 3.053113e-16 6.860831e-16 3
3 S08-P002--y__d--c032 80 3 1.19850914680120277175189744995e-94 False 0.0 1.124101e-15 4.163336e-17 0.000000e+00 27
4 S08-P002--y__d--c057 80 1 2.06120788340245935915176229414e-81 True 1.17766223607418525420750812454e-72 2.930134e-01 1.465067e-01 1.181700e-16 56
5 S08-P002--y__d--c059 80 1 2.51066706357961643133869875367e-81 True 2.26871608925176070353895646725e-72 3.432996e-01 1.716498e-01 4.670627e-17 58
6 S08-P003--y__d--c032 80 2 2.10163500389625873145697001252e-84 False 0.0 4.093947e-16 1.387779e-17 8.499657e-19 30
7 S08-P003--y__d--c057 80 1 6.83269065703205744601015941077e-83 False 0.0 7.927536e-02 1.985109e-02 1.047019e-16 56
8 S08-P003--y__d--c059 80 1 2.59080168136710839639672973673e-82 False 0.0 9.735706e-02 2.437689e-02 7.275429e-17 58
9 S08-P004--y__d--c057 80 1 7.69116102623969918694390339269e-82 False 0.0 3.108624e-15 5.551115e-17 1.133726e-18 56
10 S08-P004--y__d--c059 80 1 9.34139965471794676613702775921e-83 False 0.0 1.807582e-15 3.122502e-17 1.673858e-17 58

The high-precision gap concerns the stated numerical objective, not data accuracy or statistical uncertainty. The near-zero coefficient makes its minimizer very sensitive to the precise objective. Large differences from default sparsified weights can coexist with essentially unchanged fitted donor predictions.