PageSourceSearch

https://www.tuned.org.uk/assets/js/panel3/chart-headk.js

js tuned.org.uk collected 2026-09-25 19:57:22 UTC 4,263 bytes, 115 lines download raw bytes

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.