| <!DOCTYPE html> |
| <html lang="fr"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>pass@k — Homogène vs Dynamique sur SWE-bench Lite</title> |
| <link rel="preconnect" href="https://fonts.googleapis.com"> |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/dist/tabler-icons.min.css"> |
| <style> |
| * { box-sizing: border-box; margin: 0; padding: 0; } |
| :root { |
| --color-background-primary: #ffffff; |
| --color-background-secondary: #f5f5f4; |
| --color-background-tertiary: #f0efed; |
| --color-text-primary: #1a1a1a; |
| --color-text-secondary: #6b7280; |
| --color-text-tertiary: #9ca3af; |
| --color-border-tertiary: rgba(0,0,0,0.08); |
| --color-border-secondary: rgba(0,0,0,0.15); |
| --border-radius-md: 8px; |
| --border-radius-lg: 12px; |
| --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; |
| } |
| @media (prefers-color-scheme: dark) { |
| :root { |
| --color-background-primary: #1a1a1a; |
| --color-background-secondary: #262626; |
| --color-background-tertiary: #2a2a2a; |
| --color-text-primary: #f5f5f4; |
| --color-text-secondary: #a1a1aa; |
| --color-text-tertiary: #71717a; |
| --color-border-tertiary: rgba(255,255,255,0.08); |
| --color-border-secondary: rgba(255,255,255,0.15); |
| } |
| } |
| body { |
| font-family: var(--font-sans); |
| background: var(--color-background-tertiary); |
| color: var(--color-text-primary); |
| padding: 2rem; |
| min-height: 100vh; |
| } |
| .container { |
| max-width: 720px; |
| margin: 0 auto; |
| background: var(--color-background-primary); |
| border-radius: var(--border-radius-lg); |
| padding: 1.5rem; |
| border: 0.5px solid var(--color-border-tertiary); |
| } |
| h1 { |
| font-size: 16px; |
| font-weight: 500; |
| margin-bottom: 4px; |
| color: var(--color-text-primary); |
| } |
| .subtitle { |
| font-size: 12px; |
| color: var(--color-text-secondary); |
| margin-bottom: 1.5rem; |
| line-height: 1.5; |
| } |
| |
| input[type=range] { |
| accent-color: #378add; |
| } |
| button { |
| color: var(--color-text-primary); |
| background: var(--color-background-secondary); |
| border: 0.5px solid var(--color-border-secondary); |
| border-radius: var(--border-radius-md); |
| cursor: pointer; |
| font-family: var(--font-sans); |
| } |
| button:hover { background: var(--color-background-tertiary); } |
| button:disabled { opacity: 0.5; cursor: not-allowed; } |
| .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <h1>pass@k — Homogène vs Dynamique (Algo 2)</h1> |
| <p class="subtitle"> |
| Simulation Monte Carlo sur SWE-bench Lite (300 tâches, n=250 runs/tâche oracle) · |
| Plan factoriel seeds monde × seeds ordre · MSE, biais² et variance en pp²<br> |
| Données : Jimenez et al. 2024 · Méthode dynamique : Kazdan et al. 2025 (arXiv 2510.05197) |
| </p> |
|
|
| <h2 class="sr-only">Comparaison biais, variance et MSE entre allocation homogène et dynamique sur SWE-bench Lite</h2> |
| <div style="padding:1rem 0 0;"> |
|
|
| <div style="display:flex;align-items:center;gap:10px;margin-bottom:10px;"> |
| <label style="font-size:13px;color:var(--color-text-secondary);min-width:96px;">n (runs/tâche)</label> |
| <input type="range" min="2" max="60" step="1" value="10" id="sl-n" style="flex:1;"> |
| <span style="font-size:13px;font-weight:500;min-width:32px;text-align:right;" id="vn">10</span> |
| </div> |
| <div style="display:flex;align-items:center;gap:10px;margin-bottom:10px;"> |
| <label style="font-size:13px;color:var(--color-text-secondary);min-width:96px;">T (nb tâches)</label> |
| <input type="range" min="10" max="300" step="10" value="100" id="sl-T" style="flex:1;"> |
| <span style="font-size:13px;font-weight:500;min-width:32px;text-align:right;" id="vT">100</span> |
| </div> |
| <div style="display:flex;align-items:center;gap:10px;margin-bottom:10px;"> |
| <label style="font-size:13px;color:var(--color-text-secondary);min-width:96px;">k (pass@k)</label> |
| <input type="range" min="1" max="20" step="1" value="5" id="sl-k" style="flex:1;"> |
| <span style="font-size:13px;font-weight:500;min-width:32px;text-align:right;" id="vk">5</span> |
| </div> |
| <div style="display:flex;align-items:center;gap:10px;margin-bottom:14px;"> |
| <label style="font-size:13px;color:var(--color-text-secondary);min-width:96px;">seeds monde</label> |
| <input type="range" min="1" max="10" step="1" value="5" id="sl-sw" style="flex:1;"> |
| <span style="font-size:13px;font-weight:500;min-width:32px;text-align:right;" id="vsw">5</span> |
| <label style="font-size:13px;color:var(--color-text-secondary);min-width:76px;text-align:right;">seeds ordre</label> |
| <input type="range" min="1" max="10" step="1" value="5" id="sl-so" style="flex:1;"> |
| <span style="font-size:13px;font-weight:500;min-width:32px;text-align:right;" id="vso">5</span> |
| </div> |
|
|
| <button id="runbtn" onclick="runAll()" style="width:100%;padding:9px;font-size:13px;font-weight:500;background:var(--color-background-secondary);border:0.5px solid var(--color-border-secondary);border-radius:8px;cursor:pointer;margin-bottom:16px;color:var(--color-text-primary);"> |
| <i class="ti ti-player-play" style="vertical-align:-2px;margin-right:4px;" aria-hidden="true"></i>Lancer la simulation |
| </button> |
|
|
| <div style="background:var(--color-background-secondary);border-radius:10px;padding:12px 14px;margin-bottom:16px;"> |
| <div style="display:grid;grid-template-columns:auto 1fr 1fr;gap:8px 16px;align-items:center;font-size:13px;"> |
| <div></div> |
| <div style="text-align:center;font-weight:500;color:#378add;">Homogène</div> |
| <div style="text-align:center;font-weight:500;color:#e2855a;">Dynamique</div> |
| <div style="color:var(--color-text-secondary);">Biais (pp)</div> |
| <div style="text-align:center;" id="t-hbias">—</div> |
| <div style="text-align:center;" id="t-dbias">—</div> |
| <div style="color:var(--color-text-secondary);">Variance (pp²)</div> |
| <div style="text-align:center;" id="t-hvar">—</div> |
| <div style="text-align:center;" id="t-dvar">—</div> |
| <div style="color:var(--color-text-secondary);font-weight:500;border-top:0.5px solid var(--color-border-tertiary);padding-top:8px;">MSE (pp²)</div> |
| <div style="text-align:center;font-weight:500;border-top:0.5px solid var(--color-border-tertiary);padding-top:8px;" id="t-hmse">—</div> |
| <div style="text-align:center;font-weight:500;border-top:0.5px solid var(--color-border-tertiary);padding-top:8px;" id="t-dmse">—</div> |
| </div> |
| <div style="text-align:center;margin-top:12px;padding-top:10px;border-top:0.5px solid var(--color-border-tertiary);font-size:13px;"> |
| <span style="color:var(--color-text-secondary);">Méthode la plus précise (MSE min) : </span> |
| <span style="font-weight:500;" id="t-winner">—</span> |
| </div> |
| </div> |
|
|
| <div style="display:flex;gap:0;margin-bottom:14px;border-bottom:1px solid var(--color-border-tertiary);"> |
| <button id="tab-mse" onclick="switchTab('mse')" style="padding:7px 12px;font-size:13px;background:none;border:none;border-bottom:2px solid #378add;color:var(--color-text-primary);font-weight:500;cursor:pointer;margin-bottom:-1px;">MSE vs k</button> |
| <button id="tab-msen" onclick="switchTab('msen')" style="padding:7px 12px;font-size:13px;background:none;border:none;border-bottom:2px solid transparent;color:var(--color-text-secondary);cursor:pointer;margin-bottom:-1px;">MSE vs n</button> |
| <button id="tab-mseT" onclick="switchTab('mseT')" style="padding:7px 12px;font-size:13px;background:none;border:none;border-bottom:2px solid transparent;color:var(--color-text-secondary);cursor:pointer;margin-bottom:-1px;">MSE vs T</button> |
| <button id="tab-decomp" onclick="switchTab('decomp')" style="padding:7px 12px;font-size:13px;background:none;border:none;border-bottom:2px solid transparent;color:var(--color-text-secondary);cursor:pointer;margin-bottom:-1px;">Biais²/Var</button> |
| </div> |
|
|
| <div id="legend-line" style="display:flex;gap:18px;margin-bottom:10px;font-size:12px;color:var(--color-text-secondary);"> |
| <span style="display:flex;align-items:center;gap:6px;"><span style="width:20px;height:2px;background:#378add;display:inline-block;"></span>Homogène</span> |
| <span style="display:flex;align-items:center;gap:6px;"><span style="width:20px;height:2px;background:#e2855a;display:inline-block;"></span>Dynamique</span> |
| </div> |
|
|
| <div style="position:relative;width:100%;height:290px;"> |
| <canvas id="myChart" role="img" aria-label="MSE des deux méthodes">Comparaison de l'erreur quadratique moyenne des deux méthodes.</canvas> |
| </div> |
|
|
| <p id="status" style="font-size:12px;color:var(--color-text-tertiary);margin-top:10px;text-align:center;">Règle les paramètres puis lance la simulation.</p> |
| </div> |
|
|
| <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script> |
| <script> |
| const RAW=[{"n":250,"c":18},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":193},{"n":250,"c":7},{"n":250,"c":0},{"n":250,"c":181},{"n":250,"c":2},{"n":250,"c":1},{"n":250,"c":0},{"n":250,"c":235},{"n":250,"c":113},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":91},{"n":250,"c":0},{"n":250,"c":236},{"n":250,"c":28},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":235},{"n":250,"c":196},{"n":250,"c":1},{"n":250,"c":220},{"n":250,"c":99},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":57},{"n":250,"c":220},{"n":250,"c":19},{"n":250,"c":196},{"n":250,"c":220},{"n":250,"c":228},{"n":250,"c":220},{"n":250,"c":113},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":220},{"n":250,"c":196},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":220},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":0},{"n":250,"c":241},{"n":250,"c":0}]; |
| |
| function mb32(s){return function(){let t=s+=0x6D2B79F5;t=Math.imul(t^t>>>15,t|1);t^=t+Math.imul(t^t>>>7,t|61);return((t^t>>>14)>>>0)/4294967296;};} |
| function lgamma(x){const g=7,c=[0.99999999999980993,676.5203681218851,-1259.1392167224028,771.32342877765313,-176.61502916214059,12.507343278686905,-0.13857109526572012,9.9843695780195716e-6,1.5056327351493116e-7];if(x<0.5)return Math.log(Math.PI/Math.sin(Math.PI*x))-lgamma(1-x);x-=1;let a=c[0];const t=x+g+0.5;for(let i=1;i<g+2;i++)a+=c[i]/(x+i);return 0.5*Math.log(2*Math.PI)+(x+0.5)*Math.log(t)-t+Math.log(a);} |
| function logB(n,k){if(k<0||k>n)return -Infinity;return lgamma(n+1)-lgamma(k+1)-lgamma(n-k+1);} |
| function betaln(a,b){return lgamma(a)+lgamma(b)-lgamma(a+b);} |
| |
| function sampleTasks(T,rng){const idx=Array.from({length:RAW.length},(_,i)=>i);for(let i=idx.length-1;i>0;i--){const j=Math.floor(rng()*(i+1));[idx[i],idx[j]]=[idx[j],idx[i]];}return idx.slice(0,T).map(i=>RAW[i]);} |
| function oracle(tasks,k){let s=0;for(const t of tasks){const v=logB(t.n-t.c,k)-logB(t.n,k);s+=v===-Infinity?1:1-Math.exp(v);}return s/tasks.length;} |
| function buildPools(tasks,rng){return tasks.map(t=>{const arr=new Int8Array(t.n);for(let i=0;i<t.c;i++)arr[i]=1;for(let i=arr.length-1;i>0;i--){const j=Math.floor(rng()*(i+1));const tmp=arr[i];arr[i]=arr[j];arr[j]=tmp;}return arr;});} |
| |
| function homogEst(tasks,n,k,rng){ |
| const pools=buildPools(tasks,rng);let s=0; |
| for(let i=0;i<tasks.length;i++){let c=0;const p=pools[i];for(let r=0;r<n;r++)c+=p[r]||0;const v=logB(n-c,k)-logB(n,k);s+=v===-Infinity?1:1-Math.exp(v);} |
| return s/tasks.length; |
| } |
| |
| function nelderMead(f,x0){let sim=[x0.slice(),[x0[0]+0.5,x0[1]],[x0[0],x0[1]+0.5]];let fv=sim.map(p=>f(p[0],p[1]));for(let it=0;it<300;it++){const ord=[0,1,2].sort((a,b)=>fv[a]-fv[b]);sim=ord.map(i=>sim[i]);fv=ord.map(i=>fv[i]);if(Math.abs(fv[2]-fv[0])<1e-6)break;const cx=(sim[0][0]+sim[1][0])/2,cy=(sim[0][1]+sim[1][1])/2;const rx=cx+(cx-sim[2][0]),ry=cy+(cy-sim[2][1]);const fr=f(rx,ry);if(fr<fv[0]){const ex=cx+2*(rx-cx),ey=cy+2*(ry-cy);const fe=f(ex,ey);if(fe<fr){sim[2]=[ex,ey];fv[2]=fe;}else{sim[2]=[rx,ry];fv[2]=fr;}}else if(fr<fv[1]){sim[2]=[rx,ry];fv[2]=fr;}else{const cx2=cx+0.5*(sim[2][0]-cx),cy2=cy+0.5*(sim[2][1]-cy);const fc=f(cx2,cy2);if(fc<fv[2]){sim[2]=[cx2,cy2];fv[2]=fc;}else{for(let i=1;i<3;i++){sim[i]=[sim[0][0]+0.5*(sim[i][0]-sim[0][0]),sim[0][1]+0.5*(sim[i][1]-sim[0][1])];fv[i]=f(sim[i][0],sim[i][1]);}}}}return sim[0];} |
| |
| function dynEst(tasks,budget,k,rng){ |
| const pools=buildPools(tasks,rng);const ptr=new Int32Array(tasks.length);const m=tasks.length; |
| const succ=new Int32Array(m),att=new Int32Array(m); |
| for(let t=0;t<budget;t++){ |
| let sMin=Infinity;for(let i=0;i<m;i++)if(succ[i]<sMin)sMin=succ[i]; |
| let aMin=Infinity;for(let i=0;i<m;i++)if(succ[i]===sMin&&att[i]<aMin)aMin=att[i]; |
| const H=[];for(let i=0;i<m;i++)if(succ[i]===sMin&&att[i]===aMin)H.push(i); |
| const it=H[Math.floor(rng()*H.length)];att[it]++; |
| const p=pools[it];succ[it]+=(ptr[it]<p.length?p[ptr[it]++]:(rng()<tasks[it].c/tasks[it].n?1:0)); |
| } |
| const fit=nelderMead((a,b)=>{if(a<=0||b<=0)return 1e10;const lab=betaln(a,b);let ll=0;for(let i=0;i<m;i++){if(att[i]===0)continue;ll+=logB(att[i],succ[i])+betaln(succ[i]+a,att[i]-succ[i]+b)-lab;}return-ll;},[1,1]); |
| const a=Math.max(1e-4,fit[0]),b=Math.max(1e-4,fit[1]); |
| return 1-Math.exp(betaln(a,b+k)-betaln(a,b)); |
| } |
| |
| function meanArr(a){return a.reduce((x,y)=>x+y,0)/a.length;} |
| function varArr(a){const m=meanArr(a);return meanArr(a.map(x=>(x-m)**2));} |
| |
| function metrics(T,n,k,nw,no){ |
| const hE=[],dE=[]; |
| for(let w=0;w<nw;w++){ |
| const tasks=sampleTasks(T,mb32(1000+w*37)); |
| const truth=oracle(tasks,k); |
| for(let o=0;o<no;o++){ |
| hE.push(homogEst(tasks,n,k,mb32(9000+w*100+o*7))-truth); |
| dE.push(dynEst(tasks,T*n,k,mb32(5000+w*100+o*13))-truth); |
| } |
| } |
| return{ |
| hBias:meanArr(hE)*100, hVar:varArr(hE)*1e4, hMse:meanArr(hE.map(x=>x*x))*1e4, |
| dBias:meanArr(dE)*100, dVar:varArr(dE)*1e4, dMse:meanArr(dE.map(x=>x*x))*1e4 |
| }; |
| } |
| |
| let tab='mse',ch=null; |
| function setTabStyle(a){['mse','msen','mseT','decomp'].forEach(t=>{const b=document.getElementById('tab-'+t);b.style.borderBottomColor=t===a?'#378add':'transparent';b.style.color=t===a?'var(--color-text-primary)':'var(--color-text-secondary)';b.style.fontWeight=t===a?'500':'400';});} |
| |
| function updateTable(m){ |
| document.getElementById('t-hbias').textContent=(m.hBias>=0?'+':'')+m.hBias.toFixed(3); |
| document.getElementById('t-dbias').textContent=(m.dBias>=0?'+':'')+m.dBias.toFixed(3); |
| document.getElementById('t-hvar').textContent=m.hVar.toFixed(3); |
| document.getElementById('t-dvar').textContent=m.dVar.toFixed(3); |
| document.getElementById('t-hmse').textContent=m.hMse.toFixed(3); |
| document.getElementById('t-dmse').textContent=m.dMse.toFixed(3); |
| document.getElementById('t-hmse').style.color=m.hMse<m.dMse?'#1D9E75':'var(--color-text-primary)'; |
| document.getElementById('t-dmse').style.color=m.dMse<m.hMse?'#1D9E75':'var(--color-text-primary)'; |
| const wEl=document.getElementById('t-winner'); |
| wEl.textContent=(m.hMse<m.dMse?'Homogène':'Dynamique')+' (MSE '+Math.min(m.hMse,m.dMse).toFixed(3)+' vs '+Math.max(m.hMse,m.dMse).toFixed(3)+')'; |
| wEl.style.color=m.hMse<m.dMse?'#378add':'#e2855a'; |
| } |
| |
| function renderLine(labels,h,d,xl){ |
| document.getElementById('legend-line').style.display='flex'; |
| if(ch)ch.destroy(); |
| ch=new Chart(document.getElementById('myChart').getContext('2d'),{ |
| type:'line', |
| data:{labels,datasets:[ |
| {label:'Homogène',data:h,borderColor:'#378add',backgroundColor:'transparent',borderWidth:2,pointRadius:2,tension:0.25}, |
| {label:'Dynamique',data:d,borderColor:'#e2855a',backgroundColor:'transparent',borderWidth:2,pointRadius:2,tension:0.25} |
| ]}, |
| options:{responsive:true,maintainAspectRatio:false, |
| plugins:{legend:{display:false},tooltip:{callbacks:{label:c=>c.dataset.label+': '+c.parsed.y.toFixed(3)+' pp²'}}}, |
| scales:{ |
| x:{title:{display:true,text:xl,color:'#888',font:{size:11}},ticks:{color:'#888',font:{size:10},maxTicksLimit:12},grid:{color:'rgba(128,128,128,0.1)'}}, |
| y:{title:{display:true,text:'MSE (pp²)',color:'#888',font:{size:11}},ticks:{color:'#888',font:{size:10}},grid:{color:'rgba(128,128,128,0.1)'},min:0} |
| } |
| } |
| }); |
| } |
| |
| function renderBar(labels,datasets,xl){ |
| document.getElementById('legend-line').style.display='none'; |
| if(ch)ch.destroy(); |
| ch=new Chart(document.getElementById('myChart').getContext('2d'),{ |
| type:'bar',data:{labels,datasets}, |
| options:{responsive:true,maintainAspectRatio:false, |
| plugins:{legend:{display:true,position:'top',labels:{font:{size:11},boxWidth:12,boxHeight:12,color:'#888'}},tooltip:{callbacks:{label:c=>c.dataset.label+': '+c.parsed.y.toFixed(3)+' pp²'}}}, |
| scales:{ |
| x:{stacked:true,title:{display:true,text:xl,color:'#888',font:{size:11}},ticks:{color:'#888',font:{size:10},maxTicksLimit:12},grid:{display:false}}, |
| y:{stacked:true,title:{display:true,text:'pp²',color:'#888',font:{size:11}},ticks:{color:'#888',font:{size:10}},grid:{color:'rgba(128,128,128,0.1)'},min:0} |
| } |
| } |
| }); |
| } |
| |
| function runAll(){ |
| const n=+document.getElementById('sl-n').value,T=+document.getElementById('sl-T').value,k=+document.getElementById('sl-k').value; |
| const nw=+document.getElementById('sl-sw').value,no=+document.getElementById('sl-so').value; |
| const btn=document.getElementById('runbtn'),status=document.getElementById('status'); |
| btn.disabled=true; status.textContent='Simulation en cours…'; |
| |
| setTimeout(()=>{ |
| updateTable(metrics(T,n,k,nw,no)); |
| const sw=Math.min(nw,3),so=Math.min(no,3); |
| let labels=[],h=[],d=[]; |
| |
| if(tab==='mse'){ |
| const kmax=Math.min(n,20); |
| for(let ki=1;ki<=kmax;ki++){const m=metrics(T,n,ki,sw,so);labels.push(ki);h.push(+m.hMse.toFixed(4));d.push(+m.dMse.toFixed(4));} |
| renderLine(labels,h,d,'k'); |
| } else if(tab==='msen'){ |
| const nmax=Math.min(60,250);const step=Math.max(1,Math.floor(nmax/16)); |
| for(let ni=Math.max(k,2);ni<=nmax;ni+=step){const m=metrics(T,ni,k,sw,so);labels.push(ni);h.push(+m.hMse.toFixed(4));d.push(+m.dMse.toFixed(4));} |
| renderLine(labels,h,d,'n (runs/tâche)'); |
| } else if(tab==='mseT'){ |
| const tmax=Math.min(300,RAW.length);const step=Math.max(10,Math.floor(tmax/15)); |
| for(let Ti=step;Ti<=tmax;Ti+=step){const m=metrics(Ti,n,k,sw,so);labels.push(Ti);h.push(+m.hMse.toFixed(4));d.push(+m.dMse.toFixed(4));} |
| renderLine(labels,h,d,'T (nb tâches)'); |
| } else { |
| const kmax=Math.min(n,20);let hb=[],hv=[],db=[],dv=[]; |
| for(let ki=1;ki<=kmax;ki++){const m=metrics(T,n,ki,sw,so);labels.push(ki);hb.push(+(m.hBias*m.hBias).toFixed(4));hv.push(+m.hVar.toFixed(4));db.push(+(m.dBias*m.dBias).toFixed(4));dv.push(+m.dVar.toFixed(4));} |
| renderBar(labels,[ |
| {label:'Homog biais²',data:hb,backgroundColor:'#185fa5',stack:'H'}, |
| {label:'Homog var',data:hv,backgroundColor:'#85b7eb',stack:'H'}, |
| {label:'Dyn biais²',data:db,backgroundColor:'#993c1d',stack:'D'}, |
| {label:'Dyn var',data:dv,backgroundColor:'#f0997b',stack:'D'} |
| ],'k'); |
| } |
| |
| btn.disabled=false; |
| status.textContent=`Terminé — ${nw}×${no} seeds (table), ${sw}×${so} seeds (courbe).`; |
| },50); |
| } |
| |
| function switchTab(t){tab=t;setTabStyle(t);runAll();} |
| ['sl-n','sl-T','sl-k','sl-sw','sl-so'].forEach(id=>{ |
| const key='v'+id.replace('sl-',''); |
| document.getElementById(id).addEventListener('input',()=>document.getElementById(key).textContent=document.getElementById(id).value); |
| }); |
| runAll(); |
| </script> |
|
|
| </div> |
| </body> |
| </html> |