1/** 2 * chart-headk.js â plot_headk_sweep() port 3 * 3 line charts with ±1 std shaded band: 4 * 1. Mean Tail/Head Ratio vs HEAD_K 5 * 2. Mean Tail CV vs HEAD_K 6 * 3. Mean Tail Decay vs HEAD_K 7 * Fetches: cve_headk_sweep.csv 8 */ 9const HEADK_BASE = 'https://raw.githubusercontent.com/tuned-org-uk/pyarrowspace/main/neurips/CVE/output/v2/'; 10const HEADK_COLORS = { Cosine: '#1f77b4', Hybrid: '#ff7f0e', Taumode: '#2ca02c' }; 11 12async function fetchCSVHeadK(url) { 13 const r = await fetch(url); 14 const txt = await r.text(); 15 const lines = txt.trim().split('\n'); 16 const headers = lines[0].split(','); 17 return lines.slice(1).map(l => { 18 const vals = l.split(','); 19 const obj = {}; 20 headers.forEach((h, i) => obj[h.trim()] = vals[i]?.trim()); 21 return obj; 22 }); 23} 24 25function normHK(raw) { 26 if (!raw) return null; 27 const r = raw.toLowerCase(); 28 if (r.includes('cosine')) return 'Cosine'; 29 if (r.includes('hybrid')) return 'Hybrid'; 30 if (r.includes('tau')) return 'Taumode'; 31 return raw; 32} 33 34const arrMean = a => a.length ? a.reduce((s,v)=>s+v,0)/a.length : NaN; 35const arrStd = a => { if(a.length<2)return 0; const m=arrMean(a); return Math.sqrt(a.reduce((s,v)=>s+(v-m)**2,0)/a.length); }; 36 37function buildHeadKCharts() { 38 fetchCSVHeadK(HEADK_BASE + 'cve_headk_sweep.csv').then(rows => { 39 const grouped = {}; 40 rows.forEach(r => { 41 const h = +r.head_k; 42 const m = normHK(r.tau_method); 43 if (!m) return; 44 if (!grouped[h]) grouped[h] = {}; 45 if (!grouped[h][m]) grouped[h][m] = { tail_to_head_ratio:[], tail_cv:[], tail_decay_rate:[] }; 46 grouped[h][m].tail_to_head_ratio.push(+r.tail_to_head_ratio); 47 grouped[h][m].tail_cv.push(+r.tail_cv); 48 grouped[h][m].tail_decay_rate.push(+r.tail_decay_rate); 49 }); 50 51 const headKs = Object.keys(grouped).map(Number).sort((a,b)=>a-b); 52 const methods = ['Cosine','Hybrid','Taumode']; 53 const container = document.getElementById('headk-container'); 54 if (!container) return; 55 container.innerHTML = ''; 56 57 [ 58 { key:'tail_to_head_ratio', title:'Mean Tail/Head Ratio vs HEAD_K', sub:'higher is better' }, 59 { key:'tail_cv', title:'Mean Tail CV vs HEAD_K', sub:'lower is better' }, 60 { key:'tail_decay_rate', title:'Mean Tail Decay vs HEAD_K', sub:'lower is better' }, 61 ].forEach(({key,title,sub}) => { 62 const canvas = document.createElement('canvas'); 63 canvas.style.marginBottom = '2.5rem'; 64 container.appendChild(canvas); 65 66 const datasets = []; 67 methods.forEach(m => { 68 const means = headKs.map(h => arrMean(grouped[h]?.[m]?.[key]||[])); 69 const stds = headKs.map(h => arrStd(grouped[h]?.[m]?.[key]||[])); 70 datasets.push({ 71 label: m, 72 data: means, 73 borderColor: HEADK_COLORS[m], 74 backgroundColor: 'transparent', 75 pointRadius: 5, tension: 0.2, order: 1, 76 }); 77 // Upper bound (fill to next = lower bound) 78 datasets.push({ 79 label: `${m} +std`, 80 data: means.map((v,i)=>v+stds[i]), 81 borderColor: 'transparent', 82 backgroundColor: HEADK_COLORS[m]+'2a', 83 pointRadius: 0, tension: 0.2, fill: '+1', order: 2, 84 }); 85 // Lower bound 86 datasets.push({ 87 label: `${m} -std`, 88 data: means.map((v,i)=>v-stds[i]), 89 borderColor: 'transparent', 90 backgroundColor: 'transparent', 91 pointRadius: 0, tension: 0.2, fill: false, order: 3, 92 }); 93 }); 94 95 new Chart(canvas, { 96 type: 'line', 97 data: { labels: headKs, datasets }, 98 options: { 99 responsive: true, 100 interaction: { mode:'index', intersect:false }, 101 plugins: { 102 title: { display:true, text:`${title} (${sub})`, font:{size:13,weight:'bold'} }, 103 legend: { labels:{ filter: item => !item.text.endsWith('+std') && !item.text.endsWith('-std') } } 104 }, 105 scales: { 106 x: { title:{display:true,text:'HEAD_K'}, ticks:{stepSize:1} }, 107 y: { title:{display:true,text:'Metric value'} } 108 } 109 } 110 }); 111 }); 112 }).catch(e => console.error('headk fetch error', e)); 113} 114
115document.addEventListener('DOMContentLoaded', buildHeadKCharts);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.